LeetCode每日一练——137. 只出现一次的数字 II
题目描述
给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。
示例 1:
输入:nums = [2,2,3,2]
输出:3
示例 2:
输入:nums = [0,1,0,1,0,1,99]
输出:99
提示:
1 <= nums.length <= 3 * 104
-231 <= nums[i] <= 231 - 1
nums 中,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次
解题思路
这题首先拍下序,这样一来,相同的数就会靠在一起,接下来我们就只需要遍历一遍数组即可,每次遍历都往后查看一个元素,如果当前指针指向的元素和后一个元素相等的话,那么就说明当前指针指向的位置和后两个位置的数都相等(根据题意可以推出),所以此时我们只需要将当前指针向后移动三位;如果当前指针指向的元素和后一位元素不相等的话,就说明当前指针指向的元素就是在这个数组中仅出现一次的那个数(解释:这里我们为什么可以直接确定当前数就是只出现一次的那个数呢?其实是因为我们每次遇到相等的两个数就将当前指针移动三位,这样一来,当前数就不可能跟前面的数相同了,因为题目已经说了除了一个仅出现一次的数以外,其余的数恰好都只出现三次,而且我们又排序了,所以就可以直接确定当前指针指向的数就是答案),我们直接返回即可。
思路一:排序(时间复杂度:O(nlogn))
1 class Solution { 2 public int singleNumber(int[] nums) { 3 int n = nums.length; 4 5 if (n == 1) { 6 return nums[0]; 7 } 8 9 // 排序 10 Arrays.sort(nums); 11 12 int i = 0; 13 while (i < n - 1) { 14 if (nums[i] == nums[i + 1]) { 15 i += 3; 16 } else { 17 return nums[i]; 18 } 19 } 20 21 // 最后一个就是 22 return nums[n - 1]; 23 } 24 }
通过反馈
思路二:map(时间复杂度:O(n))
1 class Solution { 2 public int singleNumber(int[] nums) { 3 int n = nums.length; 4 5 if (n == 1) { 6 return nums[0]; 7 } 8 9 // map 10 Map<Integer, Integer> map = new HashMap<>(); 11 for (int i = 0; i < n; i++) { 12 Integer key = map.get(nums[i]); 13 if (key == null) { 14 map.put(nums[i], 1); 15 } else { 16 map.put(nums[i], map.get(nums[i]) + 1); 17 } 18 } 19 20 Set<Integer> keySet = map.keySet(); 21 for (Integer key : keySet) { 22 if (map.get(key) == 1) { 23 return key; 24 } 25 } 26 27 return -1; 28 } 29 }
通过反馈
leetcode链接:https://leetcode-cn.com/problems/single-number-ii/