国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

[Leetcode] Find the Duplicate Number 找到重復(fù)數(shù)字

chnmagnus / 3108人閱讀

摘要:暴力法復(fù)雜度時(shí)間空間思路如果不用空間的話,最直接的方法就是選擇一個(gè)數(shù),然后再遍歷整個(gè)數(shù)組看是否有跟這個(gè)數(shù)相同的數(shù)就行了。二分法復(fù)雜度時(shí)間空間思路實(shí)際上,我們可以根據(jù)抽屜原理簡(jiǎn)化剛才的暴力法。

Find the Duplicate Number

Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.

Note: You must not modify the array (assume the array is read only). You must use only constant, O(1) extra space. Your runtime complexity should be less than O(n2). There is only one duplicate number in the array, but it could be repeated more than once.

哈希表法 復(fù)雜度

時(shí)間 O(N) 空間 O(N)

思路

遍歷數(shù)組時(shí),用一個(gè)集合記錄已經(jīng)遍歷過(guò)的數(shù),如果集合中已經(jīng)有了說(shuō)明是重復(fù)。但這樣要空間,不符合。

暴力法 復(fù)雜度

時(shí)間 O(N^2) 空間 O(1)

思路

如果不用空間的話,最直接的方法就是選擇一個(gè)數(shù),然后再遍歷整個(gè)數(shù)組看是否有跟這個(gè)數(shù)相同的數(shù)就行了。

排序法 復(fù)雜度

時(shí)間 O(NlogN) 空間 O(1)

思路

更有效的方法是對(duì)數(shù)組排序,這樣遍歷時(shí)遇到前后相同的數(shù)便是重復(fù),但這樣要修改原數(shù)組,不符合要求。

二分法 復(fù)雜度

時(shí)間 O(NlogN) 空間 O(1)

思路

實(shí)際上,我們可以根據(jù)抽屜原理簡(jiǎn)化剛才的暴力法。我們不一定要依次選擇數(shù),然后看是否有這個(gè)數(shù)的重復(fù)數(shù),我們可以用二分法先選取n/2,按照抽屜原理,整個(gè)數(shù)組中如果小于等于n/2的數(shù)的數(shù)量大于n/2,說(shuō)明1到n/2這個(gè)區(qū)間是肯定有重復(fù)數(shù)字的。比如6個(gè)抽屜,如果有7個(gè)襪子要放到抽屜里,那肯定有一個(gè)抽屜至少兩個(gè)襪子。這里抽屜就是1到n/2的每一個(gè)數(shù),而襪子就是整個(gè)數(shù)組中小于等于n/2的那些數(shù)。這樣我們就能知道下次選擇的數(shù)的范圍,如果1到n/2區(qū)間內(nèi)肯定有重復(fù)數(shù)字,則下次在1到n/2范圍內(nèi)找,否則在n/2到n范圍內(nèi)找。下次找的時(shí)候,還是找一半。

注意

我們比較的mid而不是nums[mid]

因?yàn)閙id是下標(biāo),所以判斷式應(yīng)為cnt > mid,最后返回min

代碼
public class Solution {
    public int findDuplicate(int[] nums) {
        int min = 0, max = nums.length - 1;
        while(min <= max){
            // 找到中間那個(gè)數(shù)
            int mid = min + (max - min) / 2;
            int cnt = 0;
            // 計(jì)算總數(shù)組中有多少個(gè)數(shù)小于等于中間數(shù)
            for(int i = 0; i < nums.length; i++){
                if(nums[i] <= mid){
                    cnt++;
                }
            }
            // 如果小于等于中間數(shù)的數(shù)量大于中間數(shù),說(shuō)明前半部分必有重復(fù)
            if(cnt > mid){
                max = mid - 1;
            // 否則后半部分必有重復(fù)
            } else {
                min = mid + 1;
            }
        }
        return min;
    }
}
映射找環(huán)法 復(fù)雜度

時(shí)間 O(N) 空間 O(1)

思路

假設(shè)數(shù)組中沒(méi)有重復(fù),那我們可以做到這么一點(diǎn),就是將數(shù)組的下標(biāo)和1到n每一個(gè)數(shù)一對(duì)一的映射起來(lái)。比如數(shù)組是213,則映射關(guān)系為0->2, 1->1, 2->3。假設(shè)這個(gè)一對(duì)一映射關(guān)系是一個(gè)函數(shù)f(n),其中n是下標(biāo),f(n)是映射到的數(shù)。如果我們從下標(biāo)為0出發(fā),根據(jù)這個(gè)函數(shù)計(jì)算出一個(gè)值,以這個(gè)值為新的下標(biāo),再用這個(gè)函數(shù)計(jì)算,以此類推,直到下標(biāo)超界。實(shí)際上可以產(chǎn)生一個(gè)類似鏈表一樣的序列。比如在這個(gè)例子中有兩個(gè)下標(biāo)的序列,0->2->3

但如果有重復(fù)的話,這中間就會(huì)產(chǎn)生多對(duì)一的映射,比如數(shù)組2131,則映射關(guān)系為0->2, {1,3}->1, 2->3。這樣,我們推演的序列就一定會(huì)有環(huán)路了,這里下標(biāo)的序列是0->2->3->1->1->1->1->...,而環(huán)的起點(diǎn)就是重復(fù)的數(shù)。

所以該題實(shí)際上就是找環(huán)路起點(diǎn)的題,和Linked List Cycle II一樣。我們先用快慢兩個(gè)下標(biāo)都從0開(kāi)始,快下標(biāo)每輪映射兩次,慢下標(biāo)每輪映射一次,直到兩個(gè)下標(biāo)再次相同。這時(shí)候保持慢下標(biāo)位置不變,再用一個(gè)新的下標(biāo)從0開(kāi)始,這兩個(gè)下標(biāo)都繼續(xù)每輪映射一次,當(dāng)這兩個(gè)下標(biāo)相遇時(shí),就是環(huán)的起點(diǎn),也就是重復(fù)的數(shù)。對(duì)這個(gè)找環(huán)起點(diǎn)算法不懂的,請(qǐng)參考Floyd"s Algorithm。

注意

第一次找快慢指針相遇用do-while循環(huán)

代碼
public class Solution {
    public int findDuplicate(int[] nums) {
        int slow = 0;
        int fast = 0;
        // 找到快慢指針相遇的地方
        do{
            slow = nums[slow];
            fast = nums[nums[fast]];
        } while(slow != fast);
        int find = 0;
        // 用一個(gè)新指針從頭開(kāi)始,直到和慢指針相遇
        while(find != slow){
            slow = nums[slow];
            find = nums[find];
        }
        return find;
    }
}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/64621.html

相關(guān)文章

  • [Leetcode] Contains Duplicate 包含重復(fù)

    摘要:代碼集合法復(fù)雜度時(shí)間空間思路同樣使用集合,但這次我們要維護(hù)集合的大小不超過(guò),相當(dāng)于是記錄一個(gè)寬度為的窗口中出現(xiàn)過(guò)的數(shù)字。 Contains Duplicate I Given an array of integers, find if the array contains any duplicates. Your function should return true if any v...

    rozbo 評(píng)論0 收藏0
  • 前端 | 每天一個(gè) LeetCode

    摘要:在線網(wǎng)站地址我的微信公眾號(hào)完整題目列表從年月日起,每天更新一題,順序從易到難,目前已更新個(gè)題。這是項(xiàng)目地址歡迎一起交流學(xué)習(xí)。 這篇文章記錄我練習(xí)的 LeetCode 題目,語(yǔ)言 JavaScript。 在線網(wǎng)站:https://cattle.w3fun.com GitHub 地址:https://github.com/swpuLeo/ca...我的微信公眾號(hào): showImg(htt...

    張漢慶 評(píng)論0 收藏0
  • LeetCode[287] Find the Duplicate Number

    摘要:復(fù)雜度思路每次通過(guò)二分法找到一個(gè)值之后,搜索整個(gè)數(shù)組,觀察小于等于這個(gè)數(shù)的個(gè)數(shù)。考慮,小于這個(gè)位置的數(shù)的個(gè)數(shù)應(yīng)該是小于等于這個(gè)位置的。要做的就是像找中的環(huán)一樣,考慮重復(fù)的點(diǎn)在哪里。考慮用快慢指針。代碼把一個(gè)指針?lè)呕氐介_(kāi)頭的地方 LeetCode[287] Find the Duplicate Number Given an array nums containing n + 1 in...

    canopus4u 評(píng)論0 收藏0
  • LeetCode 攻略 - 2019 年 7 月下半月匯總(100 題攻略)

    摘要:月下半旬攻略道題,目前已攻略題。目前簡(jiǎn)單難度攻略已經(jīng)到題,所以后面會(huì)調(diào)整自己,在刷算法與數(shù)據(jù)結(jié)構(gòu)的同時(shí),攻略中等難度的題目。 Create by jsliang on 2019-07-30 16:15:37 Recently revised in 2019-07-30 17:04:20 7 月下半旬攻略 45 道題,目前已攻略 100 題。 一 目錄 不折騰的前端,和咸魚(yú)有什么區(qū)別...

    tain335 評(píng)論0 收藏0
  • leetcode14 4sum

    摘要:這里需要注意及時(shí)處理掉重復(fù)的情況。那么就需要盡可能排除不可能的情況來(lái)提高計(jì)算效率。因?yàn)閿?shù)組已經(jīng)被排序,所以可以根據(jù)數(shù)組中元素的位置判斷接下來(lái)的情況是否有可能合成目標(biāo)值。 題目要求 此處為原題地址 Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d =...

    MoAir 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<