問題:在乙個長度為n的陣列裡的所有數字都在0-n~1的範圍裡,不知道重複的數字,也不知道每個重複數字重複幾次,找出陣列中所有重複的數字,如輸入,則應輸出。
要求1:能改變陣列中的數字
思路1:將陣列排序,然後遍歷陣列,找出重複的數字。時間複雜度o(nlogn),空間複雜度o(1)。
思路1的實現:
vectorfindduplicationnum(vector&testdata)
}} return res;
}
思路2:因陣列中的數字都在0~n-1的範圍內,所以若陣列中沒有重複的數字,則排序後數字i將出現在下標為i的位置,而有重複的數字時,多個位置出現同一數字。因此可以遍歷該陣列,當掃瞄到下標為i的數字時,首先比較這個數字(用m表示)與i是否相等,若相等,則接著掃瞄下乙個數字,若不相等,則比較m與第m個位置上的數字n是否相等,若相等,則m為重複的數字(第i個位置與第m個位置的值相等),若不等,則交換m與n的值,直到找到重複數字或下標為i的數字與i相等,然後掃瞄下乙個數字。時間複雜度o(n),空間複雜度o(1)。
思路2的實現
vectorfindduplicationnum(vector&testdata)
for (int i = 0; i < testdata.size(); i++)
else
}} return res;
}
要求2:不能改變陣列
思路1:遍歷陣列,統計每個數字出現的次數,將結果存入map中;遍歷map,找出重複的數字。時間複雜度o(n),空間複雜度o(n)。
思路1 的實現
vectorfindduplicationnum(vector&testdata)
auto i = count.begin();
while (i != count.end())
i++;
} return res;
}
思路2:把0~n-1的數字從中間的數字m分為兩部分,前一部分為0~m,後一部分為m+1~n-1,如果0~m的數字的數目超過m+1個,則該部分一定含有重複數字,反之,另一半的區間裡一定含有重複數字。然後繼續把包含有重複數字的區間一分為二,直到找到乙個重複數字為止。
思路2的實現
int countrange(vector&testdata, int start, int middle) //統計當前部分各數字在陣列中出現的次數。
return count;
}int findduplicationnum(vector&testdata)
if (count > middle- start + 1)
else start = middle + 1;
} return -1;
}
在該思路的中,呼叫countrange函式o(logn)次,每次需要o(n)的時間,因此總的時間複雜度為o(nlogn),空間複雜度為o(1)。但值得注意的是,該演算法中,不能保證找到所有重複的數字。 劍指offer 找出陣列中重複的數字
題目 在乙個長度為n的陣列裡的所有數字都在0 n 1的範圍內。陣列中某些數字是重複的,但是不知道有幾個數字重複了,也不知道每個數字重複了幾次,請找出陣列中任意乙個重複的數字。例如,如果輸入長度為7的陣列,那麼輸出的重複數字2或者3.分析 陣列中的數字為0 n 1的範圍內,如果再這個陣列中不存在重複的...
劍指offer 找出陣列中重複的數字
在乙個長度為 n 的陣列 nums 裡的所有數字都在 0 n 1 的範圍內。陣列中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出陣列中任意乙個重複的數字。示例 1 輸入 2,3,1,0,2,5,3 輸出 2 或 3 限制 2 n 100000 暴力求解的思路非常的直接...
劍指offer 陣列 找出陣列中重複的數字
給定乙個長度為 n 的整數陣列 nums,陣列中所有的數字都在 0 n 1 的範圍內。陣列中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出陣列中任意乙個重複的數字。注意 如果某些數字不在 0 n 1 的範圍內,或陣列中不包含重複數字,則返回 1 樣例給定 nums 2...