哈希
(2025/7/5)
1两数之和
思路
这里写(copy)一点思路:
注意到方法一的时间复杂度较高的原因是寻找 target - x 的时间复杂度过高。因此,我们需要一种更优秀的方法,能够快速寻找数组中是否存在目标元素。如果存在,我们需要找出它的索引。
使用哈希表,可以将寻找 target - x 的时间复杂度降低到从 O(N) 降低到 O(1)。
这样我们创建一个哈希表,对于每一个 x,我们首先查询哈希表中是否存在 target - x,然后将 x 插入到哈希表中,即可保证不会让 x 和自己匹配。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Solution { public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>(); int n = nums.length; for(int i = 0; i < n; ++i){ if(hashtable.containsKey(target - nums[i])) { return new int[]{hashtable.get(target - nums[i]), i}; } hashtable.put(nums[i], i); } return new int[0]; } }
|
49字母异位词分组
思路-1
由于互为字母异位词的两个字符串包含的字母相同,因此对两个字符串分别进行排序之后得到的字符串一定是相同的,故可以将排序之后的字符串作为哈希表的键。
代码-1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Solution { public List<List<String>> groupAnagrams(String[] strs) { Map<String, List<String>> map = new HashMap<String, List<String>>(); for(String str : strs){ char[] array = str.toCharArray(); Arrays.sort(array); String key = new String(array); List<String> list = map.getOrDefault(key, new ArrayList<String>()); list.add(str); map.put(key, list); } return new ArrayList<List<String>>(map.values()); } }
|
思路-2
可以将每个字母出现的次数使用字符串表示,作为哈希表的key。
代码-2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
class Solution { public List<List<String>> groupAnagrams(String[] strs) { Map<String, List<String>> map = new HashMap<String, List<String>>(); for (String str : strs){ int[] count = new int[26]; int length = str.length(); for (int i = 0; i < length; i++ ){ count[str.charAt(i) - 'a']++; } StringBuffer sb = new StringBuffer(); for(int i=0; i<26; i++){ if(count[i] != 0) { sb.append((char)('a' + i)); sb.append(count[i]); } } String key = sb.toString(); List<String> list = map.getOrDefault(key,new ArrayList<String>()); list.add(str); map.put(key,list); } return new ArrayList<List<String>>(map.values()); } }
|
128最长连续序列
思路
直接存入Set,让其自动排序,并且顺序读取。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class Solution { public int longestConsecutive(int[] nums) { Set<Integer> num = new HashSet<Integer>(); for(int n : nums){ num.add(n); }
int count = 0;
for(int n : num){ if(!num.contains(n - 1)){ int curNum = n; int curStreak = 1;
while(num.contains(curNum + 1)){ curNum += 1; curStreak += 1; }
count = Math.max(count, curStreak); } } return count; } }
|
总结
总体上将数组存入HashMap或者Set,然后遍历,判断是否满足条件,满足则计数,不满足则跳过。