劍指offer之找出數組裏重複的數字
題目描述
在一個長度爲n的數組裏的所有數字都在0到n-1的範圍內。 數組中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出數組中任意一個重複的數字。
例如,如果輸入長度爲7的數組{2,3,1,0,2,5,3},那麼對應的輸出是第一個重複的數字2。
情景比喻
這就好像亂序坐的學生根據座位號找自己的座位。只要學生不是該位置,就不停的換學生過來,直到該位置坐對了人就繼續檢查下一個座位的同學。在換學生這個過程中,如果要被換過去的學生座位上有人,就找到了重複的座位號。
搞清楚題目
首先要 搞清楚 題目的含義!!!(敲黑板)
有以下這 3 個點:
1 人家給你的數組裏面的數值是有範圍的(0到n-1)。
2 數組長度爲n。
3 只要找到 一個 重複的數字,就可以返回了。
所以思路來了:
在 把不在 i 位置上的 m 送到它該在的 m 位置上 的過程中,只要發現 m 位置上已經有了 m 就找到了重複數字 m 。
用到的工具:(for循環+while循環+if語句)
for 循環滿足:i 就在 i 位置上才進入循環。
while循環滿足: i 位置上不是 i ,是m。
while循環裏面做的事:做if判斷,找出重複數字。
if 條件句裏面做的事:判斷 i 位置的數字m在不在它該在的m位置上。不在 就交換i和m,繼續while循環。在 就找到了重複數字。
下面展示 核心代碼。
// 遍歷數組,找出重複數字。
for( int i=0;i<length;i++){
while( nums[i] != i){
int m=nums[i];//獲取第i個位置裏的值,放到m變量裏面
if( nums[m] == m ){
return i;
}
//把m送到第m個位置上,以便更新第i個位置上的值,準備進行下一次while循環
int n = nums[m];//獲取第m個位置裏的值,放到n變量裏面
nums[i]=n;
nums[m]=m;
}
}
總結:
1“只要學生不是該位置,就不停的換學生過來” 對應的就是while循環。
2“檢查下一個學生” 走的是for循環。
個人想法:
以上是我在做代碼實現的時候,把我認爲難以理解的地方(我認爲難點就在怎樣使用循環)做了思路梳理,每個人的思維方式不同,所以每個人在寫完整代碼的過程中會遇到不同的難題,只要把每個難點放大,拿出來梳理,便可以解決所有的難點。歡迎大家在評論區做寫出做算法題時自己遇到的難題,拿出來一起探討,希望能用最短的時間成本幫您解決問題。