1. 程式人生 > 其它 >LeetCode0136-只出現一次的數字

LeetCode0136-只出現一次的數字

技術標籤:LeetCode演算法leetcodejava只出現一次的數字異或操作

LeetCode0136-只出現一次的數字

題目:

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

說明:

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

示例 1:

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

示例 2:

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

分析:

如果沒有時間複雜度和空間複雜度的限制,有很多解法:

  • 使用集合儲存數字。遍歷陣列中的每個數字,如果集合中沒有該數字,則將該數字加入集合,如果集合中已經有該數字,則將該數字從集合中刪除,最後剩下的數字就是隻出現一次的數字。
  • 使用雜湊表儲存每個數字和該數字出現的次數。遍歷陣列即可得到每個數字的出現次數,並更新雜湊表,最後遍歷雜湊表,得到出現一次的數字
  • 使用集合儲存陣列中出現的所有數字,並計算陣列中的元素之和。由於集合保證元素無重複,因此計算集合中的所有元素之和的兩倍,即為每個元素出現兩次的情況下的元素之和。由於陣列中只有一個元素出現一次,其餘元素都出現兩次,因此用集合中的元素之和的兩倍減去陣列中的元素之和,剩下的數就是陣列中只出現一次的數字。

但是上述方法都不滿足條件

對於本題可以採用異或操作 ⨁ \bigoplus ,異或包含下列性質:

  • 任何數和0 的異或,結果仍然是原來的數,即 a ⨁ 0 = a a\bigoplus0=a
    a0=a
  • 任何數和其自身做異或運算,結果是 0,即 a ⨁ a = 0 a\bigoplus a=0 aa=0
  • 異或滿足交換律和結合律,即 a ⨁ b ⨁ a a\bigoplus b \bigoplus a aba = b ⨁ a ⨁ a b \bigoplus a \bigoplus a baa= b ⨁ ( a ⨁ b ) b \bigoplus (a \bigoplus b) b(ab) = b ⨁ 0 b \bigoplus 0 b0 = b b b

根據以上性質,將陣列中所有的元素進行異或操作,由於出現倆次的數字異或操作為0,最後結果即可得到出現一次的數字。

程式碼:

/**
 * 0136-只出現一次的數字
 * <p>
 * 給定一個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。
 * <p>
 * 說明:
 * <p>
 * 你的演算法應該具有線性時間複雜度。 你可以不使用額外空間來實現嗎?
 * <p>
 * 示例 1:
 * <p>
 * 輸入: [2,2,1]
 * 輸出: 1
 * <p>
 * 示例 2:
 * <p>
 * 輸入: [4,1,2,1,2]
 * 輸出: 4
 */
/** * 使用位運算 */ class Solution { public int singleNumber(int[] nums) { int single = 0; for (int num : nums) { single ^= num; } return single; } } /** * 測試 */ public class Study0136 { public static void main(String[] args) { System.out.println(new Solution().singleNumber(new int[]{2, 2, 1})); } }

結果:

在這裡插入圖片描述