劍指 offer 面試題精講圖解 | 03 . 數組中重複的數字

點擊關注上方“五分鐘學算法”,

設爲“置頂或星標”,一起成長

今天分享的題目來源於 LeetCode 上的劍指 Offer 系列 面試題03. 數組中重複的數字

題目鏈接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/

一、題目描述

找出數組中重複的數字。

在一個長度爲 n 的數組 nums 裏的所有數字都在 0~n-1 的範圍內。數組中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出數組中任意一個重複的數字。

示例 1:

輸入:
[2, 3, 1, 0, 2, 5, 3]
輸出:2 或 3 

限制:

2 <= n <= 100000

二、題目解析

注意題目描述:一個長度爲 n 的數組 nums 裏的所有數字都在 0~n-1 的 範圍內,這個 範圍 恰好與數組的下標可以一一對應。

所以我們可以執行某種操作,使索引與值一一對應即索引 0 的值爲 0,索引 1 的值爲 1。而一旦某個索引的值不只一個,則找到了重複的數字,也即發生了 哈希衝突

三、動畫描述

四、圖片描述

五、參考代碼

class Solution {
    public int findRepeatNumber(int[] nums) {
        //設索引初始值爲 i = 0
        int i = 0;
        //遍歷整個數組 nums 
        while(i < nums.length) {
            //索引 i 的值爲 i,無需執行交換操作,查看下一位
            if(nums[i] == i) {
                i++;
                continue;
            }
            //索引 nums[i] 處的值也爲 nums[i],即找到一組相同值,返回 nums[i] 即可
            if(nums[nums[i]] == nums[i]) return nums[i];
            //執行交換操作,目的是爲了使索引與值一一對應,即索引 0 的值爲 0,索引 1 的值爲 1
            int tmp = nums[i];
            nums[i] = nums[tmp];
            nums[tmp] = tmp;
        }
        //如果遍歷整個數組都沒有找到相同的值,返回 -1
        return -1;
    }
}

六、複雜度分析

時間複雜度

遍歷數組需要 O(N) 時間。

注意參考代碼裏面的關鍵字 continue,這表示在 while 的一次循環裏面,只有這次循環將 索引(i)索引值(num[i]) 匹配到了,纔會執行下一次循環。

在每一次的循環過程中,索引(i)索引值(num[i]) 匹配到後,在後續的循環過程中不會操作它們,所以雖然一開始的循環過程中,執行的交換操作較多,但在後續的循環過程中根本不需要再執行操作了。

根據均攤複雜度分析 ,總的時間複雜度爲  O(N) ,N 爲數組的長度。

空間複雜度

使用常數複雜度的額外空間,爲  O(1)

七、相關標籤

  • 數組

  • 哈希

  • 原地哈希


推薦閱讀

•   C++是如何從代碼到遊戲的?•   告訴你一個學習編程的訣竅(建議收藏)•   自學編程的八大誤區!克服它!•   新手如何有效的刷算法題(LeetCode)•   10款VS Code插件神器,第7款超級實用!•   在拼多多上班,是一種什麼樣的體驗?我tm心態崩了呀!•   寫給小白,從零開始擁有一個酷炫上線的網站!


歡迎關注我的公衆號“五分鐘學算法”,如果喜歡,麻煩點一下“在看”~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章