給定一個非空整數數組,除了某個元素只出現一次之外,其他每一個元素均出現兩次。找出那個只出現了一次的元素。算法
說明:數組
你的算法應該具備線性時間複雜度。 你能夠不使用額外空間來實現嗎?測試
示例 1:spa
輸入: [2,2,1] 輸出: 1
示例 2:code
輸入: [4,1,2,1,2] 輸出: 4
一、使用HashSetblog
1 //1.0 2 public int singleNumber(int[] nums) { 3 Set<Integer> set = new HashSet<>(); 4 //遍歷數組,把其中的值寫入set中 5 for (int a : nums) { 6 if (!set.add(a)) { 7 //若set中已有重複值,就把該值刪除,這樣遍歷結束後的值即是惟一值 8 set.remove(a); 9 } 10 } 11 return set.iterator().next(); 12 }
二、先將傳入的數組排序,再處理排序
1 //2.0 2 public int singleNumber(int[] nums) { 3 Arrays.sort(nums);//對數組進行排序 4 //由於排好序後的數組中的元素除了要尋找的那個值之外,都是成對出現的, 5 //因此,以每次遞增2的規律遍歷數組 6 for (int i = 0; i < nums.length - 1; i+=2) { 7 //當前值與它後面的值不相等,則它就是尋找值 8 if (nums[i] != nums[i + 1]) { 9 return nums[i]; 10 } 11 12 } 13 //遍歷結束後,沒有找到尋找值,則它位於數組末尾, 14 //只有這一種狀況下,遍歷纔會找不到該值 15 return nums[nums.length - 1]; 16 17 }
三、分析一下這個場景下的數組,有一個規律,即咱們要尋找的值在數組中的索引老是偶數,這樣咱們用數組中偶數下標的和減去奇數下標的和,差值就是答案索引
1 //3.0 2 public int singleNumber(int[] nums) { 3 int num = 0; 4 Arrays.sort(nums);//對數組排序 5 for (int i = 0; i < nums.length; i++) { 6 //經過i%2這個運算來判斷當前元素是奇數位仍是偶數位,只有爲偶數位時運算值才爲0 7 //若元素是偶數位,則num加上它的值,不然減去它的值 8 num = (i % 2 == 0) ? num + nums[i] : num - nums[i]; 9 } 10 return num; 11 }
四、回憶一下異或運算(^)的規則,參與運算的兩個數的值不一致時返回1,不然返回0,另外,0與任何數(a)異或的結果都爲它自己(a),利用這個特性,完成算法rem
1 //4.0 2 public int singleNumber(int[] nums) { 3 int result = 0; 4 for (int num : nums) { 5 //由於0與任何數異或的結果都是它自己,不會影響結果,因此算法入口, 6 //咱們讓0與第一個值異或,來開啓下面的運算 7 result = num ^ result; 8 } 9 return result; 10 11 }
測試方法:it
1 package onceTime; 2 3 /** 4 * 5 * @author Cone 6 * @since 2019年4月21日 7 * 8 */ 9 public class TestSolution { 10 11 public static void main(String[] args) { 12 13 Solution solution = new Solution(); 14 int[] a = new int[] { 15 4,1,2,1,2 16 }; 17 System.out.println(solution.singleNumber(a)); 18 19 } 20 21 }
以上四種方法,最後一種算法我我的是最喜歡的,它巧妙的運用了異或運算,JDK提供的排序算法確實好用,可是我更想實現本身的方法,對,本身造輪子。