題目
解題思路
與之前那道題有些相似,也是遍歷並讓數字歸位,因爲只有一位數字丟失,假設數組長度爲n,數組中的數字在[0,n]之間,
如果丟失的數字x範圍是0≤x≤n-1,則數組最大的數字n必然無處歸位(數組下標最大爲n-1),則把n所在位置的數字設爲-1,遍歷結束後-1所在位置就是沒有歸位的數字,也就是丟失的數字;
如果丟失數字是n是話,那麼數組所有數字都歸位並且沒有-1出現。
舉個栗子:
用missindex來標註丟失數字的位置,初始化爲-1
假設 4 2 5 0 1
1: 第一個數字爲4位置不對,與第5個數字1交換位置
1 2 5 0 4 missindex = -1
2: 第一個數字爲1位置不對,與第2個數字2交換位置
2 1 5 0 4 missindex = -1
3: 第一個數字爲2位置不對,與第3個數字5交換位置
5 1 2 0 4 missindex = -1
4: 第一個數字爲5位置不對,沒有第6個位置,所以把5設爲-1
-1 1 2 0 4 missindex = 0
5: 第一個數字爲-1,跳過,繼續遍歷,第1,2個數字位置正確,也跳過,第3個數字0位置錯誤,與第一個數字-1交換位置
0 1 2 -1 4 missindex = 3
6:第3個數字是-1,跳過,繼續遍歷,後面數字位置正確,遍歷結束時missindex = 3,因此丟失的數字是3
具體代碼
class Solution {
public:
void swap(vector<int>& nums, int a, int b) {
int t = nums[a];
nums[a] = nums[b];
nums[b] = t;
}
int missingNumber(vector<int>& nums) {
int missindex = -1;
for (int i = 0; i < nums.size(); i++) {
while (nums[i] != -1 && nums[i] != i && nums[i] != nums.size()) {
swap(nums, i, nums[i]);
}
if (nums[i] == nums.size()) {
nums[i] = -1;
missindex = i;
}
if (nums[i] == -1)
missindex = i;
}
return missindex == -1 ? nums.size() : missindex;
}
};
PS
說來慚愧……又看見discuss的dalao神解法……對不起我的智商拉低了leetcode題目的easy率
dalao代碼如下:
public int missingNumber(int[] nums) {
int xor = 0, i = 0;
for (i = 0; i < nums.length; i++) {
xor = xor ^ i ^ nums[i];
}
return xor ^ i;
}
有個很必要知道的定理就是:a^b^b =a, 所以最後出來的那個數字肯定只出現過一次,也就是那個丟失的數字啦~
位運算,學的棒,走遍天下都不怕!