Leetcode 尋找消失的數,尋找重複數彙總

總結,看一下題目的數字範圍是不是1到n,  如果不是的話,就需要設定一些條件即可。

 

442. Find All Duplicates in an Array

public class Solution {//如果數組裏有負數的話不可以用這種方法,只能用交換
    // some elements appear twice and others appear once.  這句話是關鍵
    public List<Integer> findDuplicates(int[] nums) {
          List<Integer> res = new ArrayList<>();
        for (int i = 0; i < nums.length; ++i) {
            while(nums[i] != nums[nums[i] - 1]){
                //int tmp = nums[i];
                //nums[i] = nums[nums[i] - 1];
               // nums[nums[i] - 1] = tmp; 注意,這裏的賦值是不正確的。 nums[i]已經改變了
                
                int tmp = nums[i];
                nums[i] = nums[tmp - 1];
                nums[tmp - 1] = tmp;
                
            }
                        
        }
        
        for(int i = 0; i < nums.length; i++){
            if(nums[i] != i + 1){
                res.add(nums[i]);
            }
        }
        return res;
        
    }
}


/* 都可以
class Solution {
public:
    vector<int> findDuplicates(vector<int>& nums) {
        vector<int> res;
        for (int i = 0; i < nums.size(); ++i) {
            if (nums[i] != nums[nums[i] - 1])
            {
                swap(nums[i], nums[nums[i] - 1]);
                --i;
            }
        }
        for (int i = 0; i < nums.size(); ++i) {
            if (nums[i] != i + 1) res.push_back(nums[i]);
        }
        return res;
    }
};



*/

448. Find All Numbers Disappeared in an Array

/*
public class Solution {
    public List<Integer> findDisappearedNumbers(int[] nums) {
        //不是自己寫的  可以運行
            // some elements appear twice and others appear once.  這句話是關鍵
        List<Integer> res = new ArrayList<Integer>();
        if(nums == null || nums.length == 0)
            return res;
        int n = nums.length;
        for(int i = 0;i < n;i++){
            int val = Math.abs(nums[i]) - 1;
            if(nums[val] > 0) 
              nums[val] = -nums[val];
        }
        
        
        
        for(int i = 0;i < n;i++){
            if(nums[i] > 0)
                res.add(i + 1);
        }
        
        
        
        return res;
    }
}
*/
public class Solution {
    public List<Integer> findDisappearedNumbers(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            while ( nums[i] != nums[nums[i] - 1]) {
                int tmp = nums[i];
                nums[i] = nums[tmp - 1];
                nums[tmp - 1] = tmp;
            }
        }
        List<Integer> res = new ArrayList<Integer>();
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] != i + 1) {
                res.add(i + 1); //這裏add是i + 1。 和Find All Duplicates in an Array 有區別。 因爲這裏是disapper. 少了某個數。 而另一道題是duplicate, i位置一定是有效值
            }
        }
        return res;
    }
}

41. First Missing Positive

public class Solution {
    public int firstMissingPositive(int[] nums) {
        if(nums.length == 0) return 1;
        for(int i = 0; i < nums.length; i++){
            while(nums[i] >= 1 && nums[i] <= nums.length  && nums[i] != nums[nums[i] - 1]){
                int tmp = nums[i];
                nums[i] = nums[nums[i] - 1];
                nums[tmp - 1] = tmp;
                
            }

            }
            
        for(int i = 0; i < nums.length; i++){
            if(nums[i] != i + 1){
                return i + 1;
            }
        }
        
        return nums.length + 1; //這裏需要注意
    }
}

268. Missing Number

public class Solution {
  
public int missingNumber(int[] nums) { 
    //也可以通過
    for(int i = 0; i< nums.length; i++){
        if(nums[i] == 0) continue;
        while(nums[i] != nums[nums[i] -1]){
             if(nums[i] == 0) break;
            int tmp = nums[i];
            nums[i ] = nums[tmp - 1];
            nums[tmp - 1] = tmp;
             if(nums[i] == 0) break;
        }

    }
    for(int i =0; i < nums.length; i++){
            if(nums[i] != i + 1){
                return i + 1;
            }
        }
        return 0;
}

}


/*
public int missingNumber(int[] nums) { //binary search
    Arrays.sort(nums);
    int left = 0, right = nums.length, mid= (left + right)/2;
    while(left < right){
        mid = (left + right)/2;
        if(nums[mid]>mid) right = mid;
        else left = mid+1;
    }
    return left;
}

*/

/*
public int missingNumber(int[] nums) { //sum
    int len = nums.length;
    int sum = (0+len)*(len+1)/2;
    for(int i=0; i<len; i++)
        sum-=nums[i];
    return sum;
}

*/


/*
public int missingNumber(int[] nums) { //xor  好好好
    int res = nums.length;
    for(int i=0; i<nums.length; i++){
        res ^= i;
        res ^= nums[i];
    }
    return res;
}

*/











287. Find the Duplicate Number

class Solution {
    public int findDuplicate(int[] nums) {
        //這種方法也可以
        for (int i = 0; i < nums.length; ++i) {
            while(nums[i] != nums[nums[i] - 1]){
                //int tmp = nums[i];
                //nums[i] = nums[nums[i] - 1];
               // nums[nums[i] - 1] = tmp; 注意,這裏的賦值是不正確的。 nums[i]已經改變了
                
                int tmp = nums[i];
                nums[i] = nums[tmp - 1];
                nums[tmp - 1] = tmp;
                
            }
                        
        }
        for(int i = 0; i < nums.length; i++){
            if(nums[i] != i + 1){
                return nums[i];
            }
        }
        return 0;
    }
}



/*
public class Solution {
    public int findDuplicate(int[] nums) {
        ///這道題的題目要求是不能改變原來數組,所以之前那兩種方法不能用
        //https://segmentfault.com/a/1190000003817671
        if (nums.length == 0) return 0;
        int left = 1;
        int right = nums.length -1 ;
        int mid = 0;
        while(left < right ){
            mid = (left + right ) >>> 1;
            int count = 0;
            for (int num : nums){
                if (num <= mid){
                    count ++;
                }
                
            }
            if(count > mid){
                right = mid;
                
            }else{
                left = mid + 1;
            }
            
            
        }
        
        return left;
        
    }
        
    
}

*/
//https://www.cnblogs.com/hiddenfox/p/3408931.html  鏈表的解釋
/*
對於數組 A = [2,6,4,1,3,1,5]
index 0 , 1, 2, 3, 4, 5, 6
value:2,  6, 4, 1, 3, 1, 5

索引是什麼? 索引是指針的相對位置/偏移量
那麼value 是什麼? 下一個位置的地址
那麼這個數組就可以轉換爲 : 0 - > 2 - > 4 -> 3 -> 1 -> 6 -> 5-> [1- >6-> 5 ->1 鏈表環] 可以看到這就是一個有環的鏈表

*/
/*
int findDuplicate3(vector<int>& nums)
{
	if (nums.size() > 1)
	{
		int slow = nums[0];
		int fast = nums[nums[0]];
		while (slow != fast)
		{
			slow = nums[slow];
			fast = nums[nums[fast]];
		}

		fast = 0;
		while (fast != slow)
		{
			fast = nums[fast];
			slow = nums[slow];
		}
		return slow;
	}
	return -1;
}
*/

136. Single Number

class Solution {
    public int singleNumber(int[] nums) {
        int res = 0;
        for(int i = 0; i < nums.length; i++){
            res = res ^ nums[i];
        }
        return res;
    }
}

137. Single Number II

public class Solution {
    public int singleNumber(int[] nums) {
        //http://blog.csdn.net/sunao2002002/article/details/46318025
        int len=nums.length;
        int result=0;
        for(int i=0;i<32;i++)
        {
            int mask=(1<<i);
            int count=0;
            for(int j=0;j<len;j++)
            {
                if((nums[j]&mask)!=0)
                {
                    count++;
                    
                }
                  
                   
                                          
            }
            
            if(count%3!=0)
                {
                  result=(result|mask);
                                      
                }
            
            
            
        }
        
        return result;
    }
}

260. Single Number III

public class Solution {
    public int[] singleNumber(int[] nums) {
        // Pass 1 : 
        // Get the XOR of the two numbers we need to find
        int diff = 0;
        for (int num : nums) {
            diff ^= num;
        }
        // Get its last set bit
        diff &= ~(diff - 1);
        
        // Pass 2 :
        int[] rets = {0, 0}; // this array stores the two numbers we will return
        for (int num : nums)
        {
            if ((num & diff) == 0) // the bit is not set
            {
                rets[0] ^= num;
            }
            else // the bit is set
            {
                rets[1] ^= num;
            }
        }
        return rets;
    }
}
/*
Why diff &= ~(diff - 1)
First, this the original formula to get the last set bit. The diff &= -diff is just an abbreviation with the knowledge of ~(diff - 1) = - (diff - 1) - 1 = -diff.

If diff is set on the least significant bit, then this is trivially provable: the least significant bit is the last set bit. After the -1 operation, this least significant bit became 0, and is the only change to all bits of diff. Then we ~ the result, which means the least significant bit gets reverted to 1, while all the other bits are guaranteed to have been reverted. Thus the least significant bit is the only bit that is left unchanged and that could survive the & operation.
If diff is unset on the least significant bit: let's focus on the rightmost occurrence of 10 in diff. The 1 bit in this 10 is the last set bit of diff. After -1 operation, this 10 becomes 01. All the 0 bits to the right of this rightmost 10 are all change to 1 bits, and all the other whatever bits to the left of this rightmost 10 would be remain unchanged:
**..**10_00..00
after -1:
**..**01_11..11
Then we do ~ operation. The **..** part would all be reverted, and none of them would survive the upcoming & operation. 01 would become back 10, and would both survive the & operation, although the bit 1 is the only one we care about. All those 11..11 part gets reverted back to 00..00 after the ~ operation, and does not matter to the & operation. Thus the only thing surviving the & operation would be the rightmost 10, or the last set bit which is within it.

Incidentally, it does not really matter which bit we choose for the second pass to succeed, but since there is an elegant way to find the rightmost set bit, then let's use that.
*/

 

 

 

 

 

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