标签:时间 利用 运用 arrays 解决方法 hashset number 它的 复杂
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1] 输出: 1
示例 2:
输入: [4,1,2,1,2] 输出: 4
1、使用HashSet
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 }
2、先将传入的数组排序,再处理
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 }
3、分析一下这个场景下的数组,有一个规律,即我们要寻找的值在数组中的索引总是偶数,这样我们用数组中偶数下标的和减去奇数下标的和,差值就是答案
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 }
4、回忆一下异或运算(^)的规则,参与运算的两个数的值不一致时返回1,否则返回0,另外,0与任何数(a)异或的结果都为它本身(a),利用这个特性,完成算法
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 }
测试方法:
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提供的排序算法确实好用,但是我更想实现自己的方法,对,自己造轮子。
标签:时间 利用 运用 arrays 解决方法 hashset number 它的 复杂
原文地址:https://www.cnblogs.com/cone/p/10746162.html