leetcode540. Single Element in a Sorted Array

題目要求

You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once. Find this single element that appears only once.java

Example 1:數組

Input: [1,1,2,3,3,4,4,8,8]
Output: 2app

Example 2:this

Input: [3,3,7,7,10,11,11]
Output: 10spa

Note:Your solution should run in O(log n) time and O(1) space.code

現有一個有序的遞增的整數數組,其中除了一個數字以外,每一個數字都出現了兩次。要求用O(log n)的時間複雜度和O(1)的空間複雜度找出只出現一次的數字。遞歸

思路一:位運算

已知 a ^ a = 0,利用這個結論,能夠對全部的數字執行異或操做,最終異或的結果就是隻出現一次的數字。element

public int singleNonDuplicate(int[] nums) {  
    int result = 0;  
    for (int num : nums) {  
        result ^= num;  
    }  
    return result;  
}

思路二:二分法

O(log n)的時間複雜度一般都和二分法有關,而這裏的二分法的思考點在於如何尋找中間位置,以及用什麼判斷邏輯來決定是繼續遞歸處理左子數字仍是右子數組。io

一旦找到合適的中間位置,咱們就應該能夠判斷出來單個數字到底是出如今左子數字仍是右子數字。那麼咱們的目標就應該是找到中間的重複數對的第一個數字。假如咱們默認左子數組中不存在單個數字,則說明中間數對應該是位於一個偶數下標上,以下:class

0 1 2 3 4
1 1 3 3 5
    ^

可是假如單個數字在左子數組,則咱們找到的中間位置偶數下標上的數字就不是重複數對的第一個下標

0 1 2 3 4
1 2 2 3 3
    ^

所以找到中間位置的偶數下標上的值,而且和後面的數字進行比較,就知道單個數字究竟在左邊仍是在右邊。

public int singleNonDuplicate2(int[] nums) {  
    int start = 0, end = nums.length - 1;  
    while (start < end) {  
        int mid = (start + end) / 2;  
        //假設左半邊子數組均爲重複數字,則默認的中間數對的第一個數字的下標必定爲偶數  
 //找到中間數對第一個數字的下標  
    if (mid % 2 == 0) {mid -= 1;}  
        //中間數對爲重複數字,說明單個數字在右半邊  
    if (nums[mid] == nums[mid + 1]) {  
            start = mid + 2;  
        } else {  
            end = mid - 1;  
        }  
    }  
    return start;  
}
相關文章
相關標籤/搜索