【LeetCode】第136題——只出現一次的數字(難度:簡單)
阿新 • • 發佈:2020-12-15
【LeetCode】第136題——只出現一次的數字(難度:簡單)
題目描述
給定一個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。
說明:
你的演算法應該具有線性時間複雜度。
-
示例 1:
輸入: [2,2,1]
輸出: 1 -
示例 2:
輸入: [4,1,2,1,2]
輸出: 4
你可以不使用額外空間來實現嗎?
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/single-number
解題思路
思路一:使用額外空間,利用ArrayList。遍歷陣列,如果ArrayList中沒有此元素則加入進數組裡,如果存在則刪掉。最後返回ArrayList元素的第0個。
思路二:(官方解法殺瘋了)。異或思路:
異或滿足交換律和結合律,因此如果把陣列中的元素從頭異或到尾,使用交換律把相同的兩個元素湊到一起,再使用結合律加入括號,相同元素異或結果為0,0與任何元素異或結果為該元素。該判斷方法充分利用重複的元素只有2個(偶數個即可)的條件,秒啊。
程式碼詳解
思路一
ArrayList
class Solution {
public int singleNumber(int[] nums) {
ArrayList<Integer> array = new ArrayList<>();
for(int i = 0; i < nums.length; ++i) { // 從頭遍歷
if (array.contains(nums[i])) { // 若存在則刪去,若不存在則加入
array.remove(Integer.valueOf(nums[i])); // 注意一定要Integer.valueOf(),理由詳見注意點模組
} else {
array.add(Integer.valueOf(nums[i]));
}
}
return array.get(0); // 獲取第0個元素(其實array裡就只有一個元素了)
}
}
思路二
異或
class Solution {
public int singleNumber(int[] nums) {
int res = 0; // 結果
for (int i : nums) {
res = res ^ i; // 從頭異或到尾,原理詳見解題思路的思路二
}
return res;
}
}
注意點
- 為何在ArrayList物件使用remove()方法時要額外使用Integer.valueOf()方法?
因為該物件的remove()方法如果傳入的引數為int型別,則刪除該列表中指定位置的元素,並返回該元素值;如果傳入的引數為Object型別(程式碼中傳入了Integer型別),則從列表中刪除指定元素的首次出現,並返回true和false表示是否刪除。即若傳入int型別,按下標刪除,若傳入物件,按元素值刪除。