1. 程式人生 > >leecode刷題(5)-- 只出現一次的數字

leecode刷題(5)-- 只出現一次的數字

leecode刷題(5)-- 只出現一次的數字

只出現一次的數字

描述:

給定一個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。

說明:

你的演算法應該具有線性時間複雜度。 你可以不使用額外空間來實現嗎?

示例:

輸入: [4,1,2,1,2]
輸出: 4

思路:

因為“除了某個元素只出現一次一次,其餘每個元素均出現兩個”,所以如果該陣列有序,且有一個元素只出現一次,以步數2向後遍歷,那麼一定會存在a[i] != a[i+1]。所以我們可以將陣列排序,然後隔兩個元素比較一次,看相鄰元素的值是否相等,若不相等,即為我們要找得出現一次的數字。

因為我們這裡用到了排序,排序的時間複雜度為 O(nlogn),不是線性時間複雜度 O(n),其實並不是很好。

程式碼如下:

import java.util.Arrays;

public class SingleNumber {
    public int singleNumber(int[] nums) {
        if (nums.length == 0) {
            return -1;
        }
        if (nums.length == 1) {
            return nums[0];
        }

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

    public static void main(String[] args) {
        int[] nums = {2,2,4,3,3};
        SingleNumber singleNumber = new SingleNumber();
        int a = singleNumber.singleNumber(nums);
        System.out.println(a);
    }
}

改進:

我們可以使用異或的方法,便能很完美的解決這個問題。

所謂異或,即為:參與運算的兩個元素,兩者的值不同返回true,兩者的值相同返回false。

通過學習計算機基礎,我們知道異或表示式有幾個規律:

  1. 恆定律:A ^ 0 = A
  2. 歸零率:A ^ A = 0
  3. 交換律:A ^ B = B ^ A
  4. 結合律:(A ^ B) ^ C = A ^ (B ^ C)

這裡我們舉個例子:

比如我們的陣列為:{2,3,2,3,1}

我們使用異或運算:

  2^3^2^3^1
= 2^2^3^3^1
= 0^0^1
= 1

所以看到這裡,大家是不是懂了,我們讓陣列中的元素做異或運算,結果便為要找的 ”只出現一次的數字“。

程式碼如下:

import java.util.Arrays;

public class SingleNumber {
    public int singleNumber(int[] nums){
        if (nums.length == 0) {
            return -1;
        }
        if (nums.length == 1) {
            return nums[0];
        }

        int result = 0;
        for (int i =0; i < nums.length; i++) {
            result = result ^ nums[i];
        }
        return result;
    }

    public static void main(String[] args) {
        int[] nums = {2,2,4,3,3};
        SingleNumber singleNumber = new SingleNumber();
        int a = singleNumber.singleNumber(nums);
        System.out.println(a);
    }
}

可以看到,時間複雜度為 O(n),符合題目線性時間複雜度的要求。