劍指offer-數組-找出數組中重複的數字

劍指offer-數組-找出數組中重複的數字

1. 題目描述

給定一個長度爲 n 的整數數組 nums,數組中所有的數字都在 0∼n−1 的範圍內。

數組中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。

請找出數組中任意一個重複的數字。

注意:如果某些數字不在 0∼n−1 的範圍內,或數組中不包含重複數字,則返回 -1;

樣例
給定 nums = [2, 3, 5, 4, 3, 2, 6, 7]。

返回 2 或 3。

oj地址:https://www.acwing.com/problem/content/14/

2. 思路

觀察數據特徵發現,有重複的數字或沒有重複數字,且數字的範圍在【0,n-1】中(特例不在【0,n-1】再特殊處理)。那問題來了,如何利用上面特徵快速的發現重複的數字?
利用數組中數字範圍在【0,n-1】可以這樣做,因爲數組下標也是【0,n-1】,所以可將每個下標i上的數nums[i],放到nums[i]對應的下標nums[i]上,即設nums[i] = x,nums[x] = y,就是把x放在nums[x]上。至於如何放?是用交換方式,nums[i] <=>nums[x] ;交換完後 ,nums[i] = y,nums[x] = x,(可看出交換後y可能等於i,也可不等於所以i上新來的y是未知的,下面主要是依據它來判斷是否重複)至此我把數字x放在了它對應的下標中,對於交換後i上的數y,繼續重複把y放在到nums[y]上,若nums[y]已經是有nums[y]== y,那i上的y就是重複的並y一定是不等i的(現在出現了兩個y,一個在對應自己下標y上,那另一個y絕對不在對應自己的位置上咯,數組下標是唯一的)。
所以繼續將nums[i]上的數一直放在它的下標的循環條件是nums[nums[i]] != nums[i] (也就是nums[y]!= y) ,循環完後判斷y是否是等於i,不等於i說明是重複的是y,等於說明y正好在自己位置上。

class Solution {
    public int duplicateInArray(int[] nums) {
        int n = nums.length;
        for(int i : nums){
            if(i <0 || i >= n)
            return -1;
        }
        for(int i=0;i<n;i++){
           
            while(nums[nums[i]] != nums[i]) {
                swap(nums, i, nums[i]);
            }
            
            if(nums[i] != i)
            return nums[i];
        }
       
        
        return -1;
    }
    void swap(int[] arr, int x,int y){
        int t = arr[x];
        arr[x] = arr[y];
       arr[y] =  t ;
    }
}
發佈了45 篇原創文章 · 獲贊 14 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章