[剑指offer]面试题03:数组中重复的数字

[剑指offer]面试题03:数组中重复的数字

题目描述

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

解题思路1

  • 最直白的想法:创建一个数组nums,用来统计输入数组中每个数字出现的次数;
    • 先遍历一遍输入数组number,更新nums的值,nums[i]的值,表示输入数组中数字i出现的次数;
    • 再遍历一遍nums,把nums[i]值大于等于2的i赋值给duplication[0],返回true
    • 只需要两次遍历,时间复杂度O(n),空间复杂度O(n)
public class Solution {
    //number 是输入的数组,length 是数组长度
    //duplication 是长度为1的数组,duplication[0]保存的是任意一个重复的元素
    public boolean duplicate(int number[],int length,int [] duplication) {
        if(number == null || length == 1){
            return false;
        }
        int[] nums = new int[length];
        for(int i =0; i< length;i++){
            nums[number[i]]++;
        }
        for(int i =0;i<length;i++){
            if(nums[i] >=2){
                duplication[0] = i;
                return true;
            }
        }
        return false;
    }

    //变种
    public boolean duplicate(int number[],int length,int [] duplication) {
        if(number == null || length == 1){
            return false;
        }
        int[] nums = new int[length];
        for(int i =0;i<length;i++){
            if(nums[number[i]] ==1){
                duplication[0] = number[i];
                return true;
            }
            nums[number[i]] =1;
        }
        return false;
    }
}

解题思路2

  • 利用数据本身的特点:长度为n的数组,数据的范围是[0~n-1],把数组升序排列,重复的数字会仅靠在一起;所以,遍历排好序的数组,比较nums[i]和nums[i+1];如果相等就表示重复了,时间复杂度O(n+nlogn),空间复杂度O(1)
import java.util.Arrays;
public class Solution {
    //number 是输入的数组,length 是数组长度
    //duplication 是长度为1的数组,duplication[0]保存的是任意一个重复的元素
    public boolean duplicate(int number[],int length,int [] duplication) {
        if(number == null || length == 1){
            return false;
        }
        Arrays.sort(number);
        for(int i =0;i<length-1;i++){
            if(number[i] == number[i+1]){
                duplication[0] = number[i];
                return true;
            }
        }
        return false;
    }
}

解题思路3

  • 《剑指offer》上提供的解法
  • 个人理解:如果输入数组中,每个数字都是无重复的,那么把输入数组number排序的话,应该满足number[i] == i。
  • 那么为了达到上述的状态,现在对于初始状态的number:
    • 如果number[i] ==i,继续向后遍历;
    • 如果number[i] ==m,比较number[i]和number[m]的值,如果相等,就表示重复了,否则把number[i]和number[m]的值交换,把m放到它应该出现的位置,直到number[i] ==i。
public class Solution {
    //number 是输入的数组,length 是数组长度
    //duplication 是长度为1的数组,duplication[0]保存的是任意一个重复的元素
    public boolean duplicate(int number[],int length,int [] duplication) {
        if(number == null || length == 1){
            return false;
        }
        for(int i =0;i<length-1;i++){
            while(number[i] != i){
                if(number[i] == number[number[i]]){
                    duplication[0] = number[i];
                    return true;
                }
                int temp = number[i];
                number[i] = number[number[i]];
                number[number[i]] = temp;
            }
        }
        return false;
    }
}

猜你喜欢

转载自blog.csdn.net/smj19920225/article/details/80196899