leecode刷題(5)-- 只出現一次的數字
阿新 • • 發佈:2018-12-28
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。
通過學習計算機基礎,我們知道異或表示式有幾個規律:
- 恆定律:A ^ 0 = A
- 歸零率:A ^ A = 0
- 交換律:A ^ B = B ^ A
- 結合律:(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),符合題目線性時間複雜度的要求。