面试题3:数组中重复的数字

题目描述

该系列文章题目和思路均参考自:《剑指Offer》

解法

思路1:对数组进行排序,例如使用快速排序(O(nlgn)),然后对数组进行遍历,判断当前元素与之后的元素是否相等,如果相等即为重复的元素。这种方式简单容易首先想到,但时间复杂度较高。

思路2:使用HashMap,遍历数组然后对每个元素判断Map中是否已经包含该元素。如果已经包含,即为重复元素。这种方式的时间复杂度为O(n),但空间复杂度较高。

思路3:以上两种方法都没有用到这个数组中的数字在0-n-1范围这一特性,根据这个特性考虑如下思路。因为数组中的元素范围都在0-n-1,因此

  • 首先对数组中的每个元素(m)进行判断,如果m=它的下标i,则继续扫描下一个元素。
  • 如果不是则拿m和第m个数字进行比较,如果相等,则说明找到了重复的数字。
  • 如果比较结果不等,就把第i个数字和第m个数字进行交换,直到发现一个重复的数字。

代码实现

/**
 * P39_问题3
 */
public class O_SearchRepeatNumber {

    public static void searchRepeatNumber(int[] array) {
        if (array.length == 0)
            return;
        for (int i = 0; i < array.length; i++) {
            while (array[i] != i) {
                if (array[i] == array[array[i]]) {
                    System.out.println(array[i]);
                    return;
                }
                // swap array[i] with array[array[i]]
                int temp = array[i];
                array[i] = array[temp];
                array[temp] = temp;
            }
        }
    }

    public static void main(String[] args) {
        int[] array = {2,3,1,0,2,5,3};
        searchRepeatNumber(array);
    }
}

题目2

 该题目和问题1中的描述很相似,但要求不能修改输入的数组。

思路1:依然使用一个HashMap作为辅助存储空间的思路依然可行。这里实现这个思路。

public class O_SearchRepeatNumber {

    public static void searchRepeatNumber_2(int[] array) {
        if (array.length == 0)
            return;
        int[] count = new int[array.length+1];
        for (int i = 0; i < count.length; i++) {
            count[i] = 0;
        }
        for (int i = 0; i < array.length; i++) {
            int temp = array[i];
            if (count[temp] == 0)
                count[temp] = 1;
            else
                System.out.println(temp);
        }
    }

    public static void main(String[] args) {
        int[] array2 = {1,3,1,0,2,5,3};
        searchRepeatNumber_2(array2);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值