美文网首页
面试题3: 数组中重复的元素

面试题3: 数组中重复的元素

作者: mark_x | 来源:发表于2019-10-02 23:35 被阅读0次
package cn.zxy.interview;

/**
 *
 * 问题一分析:
 * 1. 数组长度为n, 也就是说有n个位置; 数字在0~n-1范围内, 每个数都能放到数组特定的位置, 比如数字2放到索引为2的地方, 如果有两个2,
 * 相同位置就会出现重复的数字.
 *
 * 步骤:
 * 1. 遍历数组, 遍历到下标为i的数字x, 判断该数x是不是i
 * 2. 如果是, 判断下一个
 * 3. 如果不是, 访问以该数作为下标的元素y, 判断x的值是否与y相等
 * 4. 如果相等, 找到了重复元素;
 * 5. 如果不等, 交换x, y
 * 6. 下一个
 *
 *
 * 问题二分析:
 * 给定数组长度n+1, 数字范围为1~n, 一定会重复的原因是, 1~n不重复的数一遍共有n个数字, 想填满数组的n+1个位置, 必定有一个重复
 * 二分法: 以数字在1~7为例, 取一半的范围, 也就数1~4, 看看重复的数字在不在这个范围里, 怎么知道呢?
 * 遍历数组, 如果在1~4范围内有5或5个以上数字, 那么就在这个范围内; 反之, 就在5~7的范围内
 * 在新范围内继续二分查找, 直到start==end
 *
 */

public class A03_RepeatNumber {
    public static int findRepeatNumber(int[] a){
        // 空数组, 直接返回
        if(a == null) return -1;
        for (int i = 0; i < a.length; i++) {
            // 元素大小超出0~n-1, 返回-1
            if(a[i] >= a.length || a[i] < 0 ) return -1;
            if(a[i] == i){
                continue;
            } else {
                int y = a[a[i]];
                if(a[i] == y){
                    return a[i];
                }else{
                    swap(a, i, a[i]);
                }
            }
        }
        // 没有重复元素 返回-1
        return -1;
    }

    // 问题二
    // 例如, n=7, 数组长度为8, 元素为1~7
    public static int findRepeatDontModify(int[] a){
        if(a == null || a.length == 0) return  0;

        int start = 1;
        int end = a.length-1;
        while(start <= end){
            int mid = ((end - start) >> 1) + start;
            int count = countRange(a, start, mid);
            // 循环结束
            if(start == end){
                if(count > 1){
                    return start;
                }else{
                    break;
                }
            }

            int range = mid - start + 1;
            if (count > range){
                // 在前半段 收缩end到mid
                end = mid;
            }else{
                start = mid + 1;
            }
        }


        return -1;
    }

    private static int countRange(int[] a, int start, int mid) {
        int count = 0;
        for (int i = 0; i < a.length; i++) {
            if (a[i] >= start && a[i] <= mid){
                count++;
            }
        }
        return count;
    }

    private static void swap(int[] a, int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

    public static void main(String[] args) {
        int[] a1 = {3, 3, 1, 0, 2, 5, 3};
        int[] a2 = {3, 1, 4, 0, 5, 2 };
        int[] a3 = null;
        int num = findRepeatNumber(a3);
        System.out.println(num);

        // 问题二
        int[] b1 = {4, 2, 3, 1, 5, 6, 7, 2};
        int[] b2 = {1,2,3,4,5};
        int[] b3 = null;
        int num2 = findRepeatDontModify(b2);
        System.out.println(num2);
     }
}


相关文章

  • 数组中重复元素的处理

    1、取出数组中重复的元素(不重复的不提取,合并重复的元素) 2、合并重复的元素 (不重复的也提取) 3、剔除数组中...

  • 剑指offer面试题分类总结

    数组: 面试题3:数组中重复的数字面试题4:二维数组中的查找面试题21:调整数组顺序使奇数位于偶数前面面试题39:...

  • 剑指offer

    面试题3——数组中重复的数字 使用LinkedHashMap,有序存放。 面试题4——二维数组中的查找 首先选...

  • 面试题3: 数组中重复的元素

  • 力扣题解(数组)

    26. 删除排序数组中的重复项 面试题 16.21. 交换和 面试题 17.10. 主要元素 摩尔投票法 15. ...

  • 剑指Offer第二版 面试题3 数组中重复的数字

    剑指Offer第二版 面试题3 心得 数组中重复的数字: 题目一:找出数组中重复的数字。 在一个长度为n的数组里的...

  • 2.3.1 数组

    面试题3:数组中重复的数字 面试题4:二维数组中的查找 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一...

  • 数据结构

    面试题3:数组中重复的数字在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。数组中某些数字是重复...

  • iOS-Code Snippet

    找出数组中重复的元素

  • 26. Remove Duplicates from Sorte

    从数组中删除重复元素,返回无重复长度的数组,要使用in place算法,把返回的元素填入重复的位置即可

网友评论

      本文标题:面试题3: 数组中重复的元素

      本文链接:https://www.haomeiwen.com/subject/sgnrpctx.html