leetcodeA題之判斷重複數據,兩次,多次

本題源自leetcode  442


給定一個整數數組 a,其中1 ≤ a[i] ≤ n (n爲數組長度), 其中有些元素出現兩次而其他元素出現一次。

找到所有出現兩次的元素。

你可以不用到任何額外空間並在O(n)時間複雜度內解決這個問題嗎?


示例:

輸入:
[4,3,2,7,8,2,3,1]

輸出:
[2,3]

第一種,遍歷整個數組,將數組中的i插入i-1的位置,然後遍歷數組,如果nums[i]!=i+1也就是nums[i]本身,輸出

時間複雜度O(2n)~O(n)

var findDuplicates = function(nums) {
    for(let i = 0;i<nums.length;){
        if(nums[i]!== nums[nums[i] - 1]){
            const c = nums[i];
			nums[i] = nums[c-1];
			nums[c-1] = c;
        }else{
		i++
		}
    }

    const res = [];
    for(let i = 0; i < nums.length; i++){
            if(nums[i] !== i+1)
                res.push(nums[i]);
    }
    return res;
};
//[7,3,2,4,8,2,3,1] i = 0
//[2,3,2,4,8,7,3,1] i = 0
//[3,2,3,4,8,2,7,1] i = 0 a[0] === a[2] i+1
//[3,2,3,4,8,2,7,1] i = 1 a[1] === a[1] i++
//[3,2,3,4,8,2,7,1] i = 2 a[2] === a[2] i++
//[3,2,3,4,8,2,7,1] i = 3 a[3] === a[4-1] i++
//[3,2,3,4,8,2,7,1] i = 4 a[4] !== a[8-1] 
//[3,2,3,4,1,2,7,8] i = 4 a[4] !== a[1-1] 
//[1,2,3,4,3,2,7,8] i = 4 a[4] ===a[3-1] i++
//[1,2,3,4,3,2,7,8] i = 5 a[5] ===a[2-1] i++
//[1,2,3,4,3,2,7,8] i = 7 a[7] ===a[7-1]

第二種,nums[i] 的絕對值作爲角標,如果nums[nums[i]]>0,取nums[nums[i]]爲相反數,這樣訪問過的數nums[nums[i]]變成負數,當遇到相同的數時,nums[nums[i]]會去訪問 nums[i]的絕對值,就會找到已經置爲相反數,此時爲負數。然後就可以將nums[i]添加進入重複的數中

    let result = [];
    for (let i = 0; i < nums.length; i++) {
        let num = Math.abs(nums[i]);
        if (nums[num - 1] > 0) {
            nums[num - 1] *= -1;
       } else {
            result.push(num);
        }
    }
//let nums = [4,3,2,7,8,2,3,3,1]
//[4,3,2,-7,8,2,3,3,1]
//[4,3,2,-7,8,2,3,3,1]
//[4,3,-2,-7,8,2,3,3,1]
//[4,-3,-2,-7,8,2,3,3,1] nums[7-1]
//[4,-3,-2,-7,8,2,3,-3,1]
//[4,-3,-2,-7,8,2,3,-3,-1] i=4 nums[8-1] 
//[4,-3,-2,-7,8,2,3,-3,-1] i=5 nums[2-1] nums[1] = -3 res[2]
//[4,-3,-2,-7,8,2,3,-3,-1] i=6 nums[3-1] nums[2] = -2 res[2,3]
//[4,-3,-2,-7,8,2,3,-3,-1] i=7 nums[3-1] nums[2] = -2 res[2,3,3]
//[4,-3,-2,-7,8,2,3,-3,-1] i=8 nums[1-1] nums[0] = 4 res[2,3,3]

以上方案都是針對,數據最多隻出現兩次,若出現三次,返回的結果就會重複。

面試題03. 數組中重複的數字


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


示例 1:

輸入:
[2, 3, 1, 0, 2, 5, 3]
輸出:2 或 3 
限制:
2 <= n <= 100000

鴿巢原理/抽屜原理

你有11個蘋果,需要放進10個抽屜,勢必會有一個抽屜出現一個以上的蘋果。

還是將i放進i的角標的空間裏

var findRepeatNumber = function(nums) {
	for(let i = 0;i<nums.length;i++){
		while(nums[i]!==i){
		
			if(nums[nums[i]] !== nums[i]){
				const temp = nums[nums[i]];
				nums[nums[i]] = nums[i];
				nums[i] = temp;
			}else{
				return nums[i]
			}
		}
	}
	return -1;
};
//let arr = [0, 1, 2, 3, 4, 11, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
// [0, 1, 2, 3, 4, 11, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] i = 0,1,2,3,4
// [0, 1, 2, 3, 4, 11, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] i = 5 nums[5] = 11 nums[11]===nums[5] return nums[11]

let arr = [0, 1, 2, 3, 4, 11, 6, 7, 8, 9, 10, 12, 11, 13, 14, 15];
// [0, 1, 2, 3, 4, 11, 6, 7, 8, 9, 10, 12, 11, 13, 14, 15] i = 0,1,2,3,4
// [0, 1, 2, 3, 4, 11, 6, 7, 8, 9, 10, 12, 11, 13, 14, 15] i = 5 nums[5] = 11 nums[11]!==nums[5] 交換
// [0, 1, 2, 3, 4, 12, 6, 7, 8, 9, 10, 11, 11, 13, 14, 15] i = 6 nums[6]=6,7,8,9,10,11
// [0, 1, 2, 3, 4, 12, 6, 7, 8, 9, 10, 11, 11, 13, 14, 15] i = 12 nums[12] = 11 nums[11] === nums[12] return nus[11]

 

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