日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[Leedcode][JAVA][第136题][第137题][只出现一次的数字][位运算][HashSet][HashMap]

發布時間:2023/12/10 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Leedcode][JAVA][第136题][第137题][只出现一次的数字][位运算][HashSet][HashMap] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【問題描述】[第136,137題][只出現一次的數字]

給定一個非空整數數組,除了某個元素只出現一次以外,其余每個元素均出現了N次。找出那個只出現了一次的元素。[第136題]N= 2 輸入: [2,2,1] 輸出: 1 [第137題]N=3 輸入: [2,2,3,2] 輸出: 3

【解答思路】

[第136題]

1.HashSet

時間復雜度:O(N) 空間復雜度:O(N)

public int singleNumber(int[] nums) {HashSet<Integer> set = new HashSet<>();for (int i = 0; i < nums.length; i++) {if (!set.contains(nums[i])) {set.add(nums[i]);} else {set.remove(nums[i]);}}return set.iterator().next(); }
2. 異或

0 ⊕ 0 = 0
1 ⊕ 1 = 0
0 ⊕ 1 = 1
1 ⊕ 0 = 1

a ⊕ b ⊕ a ⊕ b ⊕ c ⊕ c ⊕ d = ( a ⊕ a ) ⊕ ( b ⊕ b ) ⊕ ( c ⊕ c ) ⊕ d = 0 ⊕ 0 ⊕ 0 ⊕ d = d

時間復雜度:O(N) 空間復雜度:O(1)

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

[第137題]

1. HashMap

時間復雜度:O(N) 空間復雜度:O(N)

public int singleNumber(int[] nums) {HashMap<Integer, Integer> map = new HashMap<>();for (int i = 0; i < nums.length; i++) {if (map.containsKey(nums[i])) {map.put(nums[i], map.get(nums[i]) + 1);} else {map.put(nums[i], 1);}}//遍歷for (Integer key : map.keySet()) { if (map.get(key) == 1) {return key;}}return -1; // 這句不會執行 }
2. 位操作

2.1 一般思路

  • 如果所有數字都出現了 3 次,那么每一列的 1 的個數就一定是 3 的倍數。
  • 之所以有的列不是 3 的倍數,就是因為只出現了 1 次的數貢獻出了 1。所以所有不是 3 的倍數的列寫 1,其他列寫 0 ,就找到了這個出現 1 次的數。
假如例子是 1 2 6 1 1 2 2 3 3 3, 3 個 1, 3 個 2, 3 個 3,1 個 6 1 0 0 1 2 0 1 0 6 1 1 0 1 0 0 1 1 0 0 1 2 0 1 0 2 0 1 0 3 0 1 1 3 0 1 1 3 0 1 1 看最右邊的一列 1001100111 有 6 個 1 再往前看一列 0110011111 有 7 個 1 再往前看一列 0010000 有 1 個 1 我們只需要把是 3 的倍數的對應列寫 0,不是 3 的倍數的對應列寫 1 也就是 1 1 0,也就是 6。

時間復雜度:O(N) 空間復雜度:O(1)

public int singleNumber(int[] nums) {int ans = 0;//考慮每一位for (int i = 0; i < 32; i++) {int count = 0;//考慮每一個數for (int j = 0; j < nums.length; j++) {//當前位是否是 1if ((nums[j] >>> i & 1) == 1) {count++;}}//1 的個數是否是 3 的倍數if (count % 3 != 0) {ans = ans | 1 << i;}}return ans; }

2.2 類似題目通用思路
二進制思想 詳情逐步思路
位運算 判相等異或^ 取位與&1 置位或|1

public int singleNumber(int[] nums) {int x1 = 0, x2 = 0, mask = 0;for (int i : nums) {x2 ^= x1 & i;x1 ^= i;mask = ~(x1 & x2);x2 &= mask;x1 &= mask;}return x1; }

【總結】

1.Iterator的API

關于Iterator主要有三個方法:hasNext()、next()、remove()

  • hasNext:沒有指針下移操作,只是判斷是否存在下一個元素

  • next:指針下移,返回該指針所指向的元素

  • remove:刪除當前指針所指向的元素,一般和next方法一起用,這時候的作用就是刪除next方法返回的元素

2. HashMap

(1) 插入鍵值對數據
public V put(K key, V value)
(2)根據鍵值獲取鍵值對值數據
public V get(Object key)
(3)獲取Map中鍵值對的個數
public int size()
(4)判斷Map集合中是否包含鍵為key的鍵值對
public boolean containsKey(Object key)
(5)判斷Map集合中是否包含值為value的鍵值對
boolean containsValue(Object value)
(6)判斷Map集合中是否沒有任何鍵值對
public boolean isEmpty()
(7)清空Map集合中所有的鍵值對
public void clear()
(8)根據鍵值刪除Map中鍵值對
public V remove(Object key)

遍歷hashMap

for (Integer key : map.keySet()) { if (map.get(key) == 1) {return key;}
3. 擴展

對于 k = 5, p = 3 怎么做,也就是每個數字出現了5 次,只有一個數字出現了 3 次。

  • 根據 k = 5,所以我們至少需要 3 個比特位。因為 2 個比特位最多計數四次。

  • 根據 k 的二進制形式是 101,所以 mask = ~(x1 & ~x2 & x3)。

  • 根據 p 的二進制是 011,所以我們最后可以把 x1 返回。

public int singleNumber(int[] nums) {int x1 = 0, x2 = 0, x3 = 0, mask = 0;for (int i : nums) {x3 ^= x2 & x1 & i;x2 ^= x1 & i;x1 ^= i;mask = ~(x1 & ~x2 & x3);x3 &= mask;x2 &= mask;x1 &= mask;}return x1; }

轉載鏈接:https://leetcode.wang/leetcode-137-Single-NumberII.html

總結

以上是生活随笔為你收集整理的[Leedcode][JAVA][第136题][第137题][只出现一次的数字][位运算][HashSet][HashMap]的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。