1. 程式人生 > >LeetCode-Set Mismatch

LeetCode-Set Mismatch

Description: The set S originally contains numbers from 1 to n. But unfortunately, due to the data error, one of the numbers in the set got duplicated to another number in the set, which results in repetition of one number and loss of another number.

Given an array nums representing the data status of this set after the error. Your task is to firstly find the number occurs twice and then find the number that is missing. Return them in the form of an array.

Example 1:

Input: nums = [1,2,2,4]
Output: [2,3]

Note:

  • The given array size will in the range [2, 10000].
  • The given array’s numbers won’t have any order.

題意:給定一個數組,包含元素[1,n],其中僅有一個元素出現兩次,一個元素出現0次,要求找出出現兩次和出現0次的元素;

解法:既然已經說明了陣列中的元素是在範圍[1,n]內的,那麼我們可以對陣列中元素對應的下標進行標記,例如對於元素2,我們標記陣列下標位置1處,表明元素2出現過,這裡因為元素都是正數,因此,我們令元素取負來標記; 舉個例子: 給定陣列arr = [4,2,2,1]

  • 對於第一個元素1,為了標記他,我們令arr[Math.abs(arr[0]) - 1] *= -1(即arr[3] = -1),得到arr = [4,2,2,-1]
  • 對於第二個元素2,令arr[Math.abs(arr[1] - 1) *= -1(即arr[1] = -2),得到arr = [4,-2,2,-1]
  • 對於第三個元素,因為arr[Math.abs(arr[2] - 1) < 0,說明這個元素出現了兩次
  • 對於第四個元素,令arr[Math.abs(arr[3]) - 1) *= -1(即arr[0] = -4),得到arr = [-4,-2,2,-1]

我們最後再遍歷得到的陣列,陣列中為正數的那個所在的位置,說明那個元素沒有出現過,即元素3;

Java
class Solution {
    public int[] findErrorNums(int[] nums) {
        int twiceNum = -1;
        int misNum = -1;
        for (int i = 0; i < nums.length; i++) {
            if (nums[Math.abs(nums[i]) - 1] < 0) {
                twiceNum = Math.abs(nums[i]);    
            } else {
                nums[Math.abs(nums[i]) - 1] *= -1;    
            }
        }
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] > 0) {
                misNum = i + 1;
                break;
            } 
        }
        return new int[] {twiceNum, misNum};
    }
}