当前位置: 首页 > news >正文

【LeetCode 面试经典150题】详细题解之哈希表篇

【LeetCode 面试经典150题】详细题解之哈希表篇

  • 1 哈希表的基础
    • 1.1 基础概念及实现
      • 1.2.1 哈希表的工作原理
      • 1.2.2 705.设计哈希集合
      • 1.2.3 706.设计哈希映射
    • 1.2 HashMap相关
      • 1.2.1 基本操作
      • 1.2.2 遍历
    • 1.3 Hashtable
    • 1.4 LinkedHashMap
    • 1.5 HashSet
      • **1.5.1基本特性**
      • 1.5.2 基本方法
      • 1.5.3 注意事项
  • 2 383.赎金信
    • 2.1 思路
    • 2.2 代码
  • 3 205.同构字符串
    • 3.1 思路
    • 3.2 代码
  • 4 290.单词规律
    • 4.1 分析
    • 4.2 代码
  • 5 242.有效的字母异位词
    • 5.1 思路
    • 5.2 代码
  • 6 49. 字母异位词分组
    • 6.1 思路
    • 6.2 代码
  • 7 1.两数之和
    • 7.1 思路
    • 7.2 代码
  • 8 202.快乐数 (需要复习)
    • 8.1 思路
    • 8.2 代码
  • 9 219.存在重复元素II
    • 9.1 思路
    • 9.2 代码
  • 10 128.最长连续序列
    • 10.1 思路
    • 10.2 代码

1 哈希表的基础

12.23 一刷

哈希表是一种基于哈希算法实现的键值对集合,提供了快速的数据插入、删除和查找功能。Java提供了HashMapHashtableLinkedHashMap等实现哈希表的类。以下是Java哈希表的一些基础概念和操作:

1.1 基础概念及实现

1.2.1 哈希表的工作原理

哈希表通过哈希函数将键(Key)映射到哈希表的索引上,然后通过这个索引来访问值(Value)。如果两个键的哈希值相同(哈希冲突),则通过链表或其他方法来解决冲突。

1.2.2 705.设计哈希集合

705. 设计哈希集合

不使用任何内建的哈希表库设计一个哈希集合(HashSet)。

实现 MyHashSet 类:

  • void add(key) 向哈希集合中插入值 key
  • bool contains(key) 返回哈希集合中是否存在这个值 key
  • void remove(key) 将给定值 key 从哈希集合中删除。如果哈希集合中没有这个值,什么也不做。
class MyHashSet {/**hash函数用于将key映射到数组中用链表法来解决哈希冲突,当两个不同的数映射到数组的同一位置时,将该数接到数组位置的链表后面*///定义hash表的长度为769private static final int BASE = 769;private LinkedList[] list;public MyHashSet() {//初始化哈希表list = new LinkedList[BASE]; //初始化LinkedListfor(int i = 0;i<BASE;i++){list[i] = new LinkedList<Integer>();}}public void add(int key) {int h = hash(key);//找到key映射到hash表中的位置Iterator<Integer> iter = list[h].iterator();while(iter.hasNext()){Integer element = iter.next();if(element == key){return;}}list[h].offerLast(key);}public void remove(int key) {int h = hash(key);Iterator<Integer> iter = list[h].iterator();while(iter.hasNext()){Integer element = iter.next();if(element == key){list[h].remove(element);return;}}}public boolean contains(int key) {int h = hash(key);Iterator<Integer> iter = list[h].iterator();while(iter.hasNext()){int element = iter.next();if(element == key){return true;}}return false;}private static int hash(int key){return key % BASE;}
}/*** Your MyHashSet object will be instantiated and called as such:* MyHashSet obj = new MyHashSet();* obj.add(key);* obj.remove(key);* boolean param_3 = obj.contains(key);*/

1.2.3 706.设计哈希映射

706. 设计哈希映射

已解答

不使用任何内建的哈希表库设计一个哈希映射(HashMap)。

实现 MyHashMap 类:

  • MyHashMap() 用空映射初始化对象
  • void put(int key, int value) 向 HashMap 插入一个键值对 (key, value) 。如果 key 已经存在于映射中,则更新其对应的值 value
  • int get(int key) 返回特定的 key 所映射的 value ;如果映射中不包含 key 的映射,返回 -1
  • void remove(key) 如果映射中存在 key 的映射,则移除 key 和它所对应的 value
class MyHashMap {/**感觉和上一个哈希表的题差不多,根据key映射到哈希表数组中的位置。只是此时,哈希表中的每个元素都应该后面还跟着value,不再是Integer了?*///定义一个Pairprivate class Pair{private int key;private int value;public Pair(int key,int value){this.key = key;this.value = value;}public int getKey(){return key;}public int getValue(){return value;}public void setValue(int value){this.value = value;}}private static final int BASE = 769;LinkedList[] list ;public MyHashMap() {list = new LinkedList[BASE];for(int i = 0;i<BASE;i++){list[i] = new LinkedList<Pair>();}}public void put(int key, int value) {int h = hash(key);Iterator<Pair> iter = list[h].iterator();while(iter.hasNext()){Pair pair = iter.next();if(pair.getKey()==key){pair.setValue(value);return;}}list[h].offerLast(new Pair(key,value));}public int get(int key) {int h = hash(key);Iterator<Pair> iter = list[h].iterator();while(iter.hasNext()){Pair pair = iter.next();if(pair.getKey()==key){return pair.getValue();}}return -1;}public void remove(int key) {int h = hash(key);Iterator<Pair> iter = list[h].iterator();while(iter.hasNext()){Pair pair = iter.next();if(pair.getKey()==key){list[h].remove(pair);return;}}}private int hash(int key){return key % BASE;}
}/*** Your MyHashMap object will be instantiated and called as such:* MyHashMap obj = new MyHashMap();* obj.put(key,value);* int param_2 = obj.get(key);* obj.remove(key);*/

1.2 HashMap相关

HashMap是Java中使用最广泛的哈希表实现,它基于Map接口,允许键值对中的键(Key)和值(Value)为null,并且不保证映射的顺序。

HashMap<String, Integer> map = new HashMap<>();
map.put("key1", 1);
map.put("key2", 2);
Integer value = map.get("key1"); // 返回1
map.remove("key2");

1.2.1 基本操作

  • put(K key, V value):将指定的值与此映射中的指定键关联。
  • get(Object key):返回指定键所映射的值。
  • remove(Object key):如果存在一个键的映射关系,则将其从映射中移除。
  • keySet():返回映射中包含的键的Set视图。
  • values():返回映射中包含的值的Collection视图。
  • entrySet():返回映射中包含的键值映射关系的Set视图

1.2.2 遍历

  1. 使用 entrySet()

entrySet() 方法返回哈希表中所有键值对的 Set 视图。这个集合中的每个元素都是一个 Map.Entry 对象,其中包含键和值。

HashMap<String, Integer> map = new HashMap<>();
map.put("key1", 1);
map.put("key2", 2);
map.put("key3", 3);for (Map.Entry<String, Integer> entry : map.entrySet()) {String key = entry.getKey();Integer value = entry.getValue();System.out.println(key + " => " + value);
}
  1. 使用 keySet()

keySet() 方法返回哈希表中所有键的 Set 视图。通过这个集合遍历所有的键,然后使用每个键来获取对应的值。

for (String key : map.keySet()) {Integer value = map.get(key);System.out.println(key + " => " + value);
}
  1. 使用 values()

如果你只对值感兴趣,可以使用 values() 方法获取哈希表中所有值的 Collection 视图。

for (Integer value : map.values()) {System.out.println(value);
}
  1. 使用 forEach 增强型 for 循环(Java 8+)

Java 8 引入了 forEach 方法,它允许使用增强型 for 循环的语法来遍历 Collection

map.forEach((key, value) -> System.out.println(key + " => " + value));
  1. 使用迭代器 Iterator

使用迭代器 Iterator 来遍历哈希表可以避免在遍历时修改集合导致的 ConcurrentModificationException

Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {Map.Entry<String, Integer> entry = iterator.next();System.out.println(entry.getKey() + " => " + entry.getValue());
}

注意事项

  • 当遍历哈希表时,如果需要修改哈希表(增加或删除元素),推荐使用迭代器 Iteratorremove 方法,或者在外部使用 removeIf 方法。
  • entrySet()keySet()values() 返回的视图反映了哈希表的当前状态,如果哈希表被修改,视图也会相应地变化。
  • 遍历哈希表的时间复杂度是 O(n),其中 n 是哈希表中的元素数量。

1.3 Hashtable

Hashtable是遗留类,也实现了Map接口,但它是同步的,不允许键或值为null,并且它的性能通常不如HashMap

Hashtable<String, Integer> htable = new Hashtable<>();
htable.put("key1", 1);
htable.put("key2", 2);
Integer value = htable.get("key1"); // 返回1
htable.remove("key2");

1.4 LinkedHashMap

LinkedHashMapHashMap的一个子类,它维护了元素的插入顺序或者访问顺序,取决于构造函数的参数。

LinkedHashMap<String, Integer> lmap = new LinkedHashMap<>();
lmap.put("key1", 1);
lmap.put("key2", 2);
Integer value = lmap.get("key1"); // 返回1
lmap.remove("key2");

1.5 HashSet

HashSet 是 Java 中的一个集合类,它实现了 Set 接口,不允许集合中有重复的元素。HashSet 的行为是由 HashMap 实现的,它使用哈希表来存储元素,因此具有很高的添加、删除和搜索效率。以下是 HashSet 的一些基础知识和遍历方法:

1.5.1基本特性

  • 不允许重复HashSet 不允许存储重复元素。
  • 无序HashSet 中的元素是无序的,这意味着元素插入和取出的顺序不一定相同。
  • 非线程安全HashSet 是非线程安全的,如果需要线程安全,可以使用 Collections.synchronizedSetCopyOnWriteArraySet

1.5.2 基本方法

// 创建
HashSet<String> set = new HashSet<>();
//添加
set.add("element1");
set.add("element2");
//删除
boolean removed = set.remove("element1"); // 返回 true 如果元素被移除,false 如果元素不存在// 判断元素是否存在
boolean contains = set.contains("element1"); // 返回 true 如果元素存在,false 否则// 遍历1 
for (String element : set) {System.out.println(element);
}// 遍历2
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {String element = iterator.next();System.out.println(element);
}// 遍历3
set.forEach(element -> System.out.println(element));// 遍历4
set.stream().forEach(System.out::println);

1.5.3 注意事项

  • HashSet 中的元素顺序不可预测,如果你需要有序的集合,可以考虑使用 TreeSet
  • 由于 HashSet 依赖于哈希函数,某些情况下可能会遇到哈希冲突,但 Java 的实现已经足够高效,冲突通常不会影响性能。
  • 当遍历或迭代 HashSet 时,如果需要修改集合,应该使用迭代器的 remove 方法,或者在外部使用 removeIf 方法。

2 383.赎金信

383. 赎金信

简单

给你两个字符串:ransomNotemagazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true ;否则返回 false

magazine 中的每个字符只能在 ransomNote 中使用一次。

示例 1:

输入:ransomNote = "a", magazine = "b"
输出:false

示例 2:

输入:ransomNote = "aa", magazine = "ab"
输出:false

示例 3:

输入:ransomNote = "aa", magazine = "aab"
输出:true

提示:

  • 1 <= ransomNote.length, magazine.length <= 105
  • ransomNotemagazine 由小写英文字母组成

2.1 思路

简单字符可以用长度为26的数组来记录字符出现的次数

    两个哈希表记录ransomNote和magazin两个字符串中,字符出现的次数,之后再一一比较由于是简单的字符,所以可以用两个长度为26的数组来记录字符出现的次数cnt_r[26]cnt_m[26]之后遍历cnt_r中的值,判断cnt_r中的每个字符出现的数量是否大于cnt_m中该字符出现的数量。小于则直接返回false

2.2 代码

class Solution {public boolean canConstruct(String ransomNote, String magazine) {/***/int[] cnt_r = new int[26];int[] cnt_m = new int[26];for(int i = 0;i<ransomNote.length();i++){cnt_r[ransomNote.charAt(i)-'a']++;}for(int i = 0;i<magazine.length();i++){cnt_m[magazine.charAt(i)-'a']++;}for(int i = 0;i<26;i++){if(cnt_r[i]>cnt_m[i]){return false;}}return true;}
}

3 205.同构字符串

205. 同构字符串

简单

给定两个字符串 st ,判断它们是否是同构的。

如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。

每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。

示例 1:

输入:s = "egg", t = "add"
输出:true

示例 2:

输入:s = "foo", t = "bar"
输出:false

示例 3:

输入:s = "paper", t = "title"
输出:true

提示:

  • 1 <= s.length <= 5 * 104
  • t.length == s.length
  • st 由任意有效的 ASCII 字符组成

3.1 思路

第一遍的时候用1个hashmap,这样会存在s->t一对一,t->s多对多的问题

两个HashMap,分别存储s-> t的映射和t-> s的映射

        用一个HashMap存储s中字符到t的映射关系,之后判断即可具体而言,对于s和t,假如是同构的,那么s中的所有字符都能映射到t中。即map[s[i]] = t[i] 会对所有的i都满足。反之,假如不满足上面条件,则说明不同构。举例s = egg,t = add遍历s和t中的每个元素,在第一个元素的时候,得出映射关系为 e->a第二个元素 g->d第三个元素 g->d,成立。具体实现则是,维持两个HashMap,分别存储s->t的映射和t->s的映射。因为一个的话会存在这种情况。s = bacdt = baba对于s中的字符满足唯一映射,但是对于t中的,比如b会映射到{b,c}不对。因此,维持两个map,s2t中以s字符为键,映射至t的字符为值t2s中以t字符为键,映射至s的字符为值从左到右遍历两个字符串,更新哈希表。出现冲突时(当前下标i对应的s[i]存在映射,但是映射不为t[i],或者t[i]存在映射,但是映射不为s[i])返回false

3.2 代码

class Solution {public boolean isIsomorphic(String s, String t) {/***/int n = s.length();Map<Character,Character> maps2t = new HashMap<>();Map<Character,Character> mapt2s = new HashMap<>();for(int i = 0;i<n;i++){char si = s.charAt(i);char ti = t.charAt(i);//冲突if(maps2t.containsKey(si) && maps2t.get(si) != ti){return false;}if(mapt2s.containsKey(ti) && mapt2s.get(ti) != si){return false;}maps2t.put(s.charAt(i),t.charAt(i));mapt2s.put(t.charAt(i),s.charAt(i));}return true;}
}

4 290.单词规律

290. 单词规律

简单

给定一种规律 pattern 和一个字符串 s ,判断 s 是否遵循相同的规律。

这里的 遵循 指完全匹配,例如, pattern 里的每个字母和字符串 s 中的每个非空单词之间存在着双向连接的对应规律。

示例1:

输入: pattern = "abba", s = "dog cat cat dog"
输出: true

示例 2:

输入:pattern = "abba", s = "dog cat cat fish"
输出: false

示例 3:

输入: pattern = "aaaa", s = "dog cat cat dog"
输出: false

提示:

  • 1 <= pattern.length <= 300
  • pattern 只包含小写英文字母
  • 1 <= s.length <= 3000
  • s 只包含小写英文字母和 ' '
  • s 不包含 任何前导或尾随对空格
  • s 中每个单词都被 单个空格 分隔

4.1 分析

和205.同构字符串差不多的题。简单题

4.2 代码

class Solution {public boolean wordPattern(String pattern, String s) {/**感觉和上一题一样,都是维护两个map,然后双向映射。思路差不多。*/String[] strs = s.split(" ");if(strs.length!=pattern.length()){return false;}Map<Character,String> c2strs = new HashMap<>();Map<String,Character> strs2c = new HashMap<>();for(int i = 0;i<strs.length;i++){char c = pattern.charAt(i);if(c2strs.containsKey(c) && !c2strs.get(c).equals(strs[i])){return false;}if(strs2c.containsKey(strs[i]) && strs2c.get(strs[i])!=c ){return false;}c2strs.put(c,strs[i]);strs2c.put(strs[i],c);}return true;}
}

5 242.有效的字母异位词

242. 有效的字母异位词

简单

给定两个字符串 st ,编写一个函数来判断 t 是否是 s 的 字母异位词。

示例 1:

输入: s = "anagram", t = "nagaram"
输出: true

示例 2:

输入: s = "rat", t = "car"
输出: false

提示:

  • 1 <= s.length, t.length <= 5 * 104
  • st 仅包含小写字母

进阶: 如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况?

5.1 思路

分析,不难

        一个cnt数组1.将s中所有出现过的字母放入cnt中记录2.遍历t,遇见一个t的字母,就在cnt中减去对应的值。假如减之后cnt值<0,则s和t的字符一定不相同。返回false3.遍历cnt,假如有不为0的数,返回false

5.2 代码

class Solution {public boolean isAnagram(String s, String t) {/***/if(s.length()!=t.length()){return false;}int[] cnt = new int[26];for(char c: s.toCharArray()){cnt[c-'a']++;}for(char c: t.toCharArray()){cnt[c-'a']--;if(cnt[c-'a']<0){return false;}}return true;}
}

6 49. 字母异位词分组

49. 字母异位词分组

中等

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

示例 1:

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]

示例 2:

输入: strs = [""]
输出: [[""]]

示例 3:

输入: strs = ["a"]
输出: [["a"]]

提示:

  • 1 <= strs.length <= 104
  • 0 <= strs[i].length <= 100
  • strs[i] 仅包含小写字母

6.1 思路

重点是用Arrays.sort排序?排序后的字符串作为key

    遍历strs,对strs中的每个str,先使用Arrays.sort排序,维持一个<String,List<String>>Map,排序后的字符串作为Key,排序前的作为Value最后,遍历Map,取出Map中的所有Value放到List结果中

6.2 代码

class Solution {public List<List<String>> groupAnagrams(String[] strs) {/***/Map<String,List<String>> map = new HashMap<>();for(String str:strs){char[] str_c = str.toCharArray();Arrays.sort(str_c);String key = new String(str_c);List<String> list = map.getOrDefault(key,new ArrayList<String>());list.add(str);map.put(key,list);}List<List<String>> res = new ArrayList<>();for(Map.Entry<String,List<String>> entry: map.entrySet()){res.add(entry.getValue());}return res;}
}

7 1.两数之和

1. 两数之和

简单

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]

提示:

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • 只会存在一个有效答案

**进阶:**你可以想出一个时间复杂度小于 O(n2) 的算法吗?

7.1 思路

经典题目,但是第一遍只想得起来暴力

  1. 暴力枚举遍历
  2. 用Map记录数字和他的下标。之后遍历的时候就能通过hashmap知道target-x是否出现过了。
枚举遍历要加速的话可以用空间换时间,用一个Map记录每个数字和他的下标。之后给原数组排序。然后双指针遍历。上面是一个思路。实际上是记录了之后,在遍历的时候能够借助hashmap知道target-x是否出现过。因此时间复杂度能从O(n^2)降到O1// int n = nums.length;// for(int i = 0;i<n;i++){//     for(int j = i+1;j<n;j++){//         if(nums[i]+nums[j]==target){//             return new int[]{i,j};//         }//     }// }// return new int[]{};

7.2 代码

class Solution {public int[] twoSum(int[] nums, int target) {Map<Integer,Integer> map = new HashMap<>();for(int i = 0;i<nums.length;i++){if(map.containsKey(target-nums[i])){return new int[]{i,map.get(target-nums[i])};}map.put(nums[i],i);}return new int[]{};}
}

8 202.快乐数 (需要复习)

202. 快乐数

简单

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
  • 如果这个过程 结果为 1,那么这个数就是快乐数。

如果 n快乐数 就返回 true ;不是,则返回 false

示例 1:

输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

示例 2:

输入:n = 2
输出:false

提示:

  • 1 <= n <= 231 - 1

8.1 思路

可以用哈希表做,用哈希表记录出现的数字,当出现重复的时候就可以返回了。

如果重复的数字为1,说明是快乐数,否则不为快乐数。

巧妙的是快慢指针判断有环的解法。具体参考下面

    快慢指针快指针每次走2步,慢指针每次走1步,二者相等时,即为1个循环周期若有环则一定能相遇,若无环也会相遇,但相遇点为1想起来了那道判断链表进环点的题。也是快慢指针。相遇后,让一个新的指针从起点开始,以和慢指针一样的速度行动,相遇的节点即为入环点。但是本题只用判断循环点是否为1即可。

8.2 代码

class Solution {public boolean isHappy(int n) {/***/int slow = n,fast = n;do{slow = bigSquareSum(slow);fast = bigSquareSum(fast);fast = bigSquareSum(fast);}while(slow != fast);if(slow==1){return true;}return false;}int bigSquareSum(int n){int sum = 0;while(n!=0){sum+= (n%10)*(n%10);n=n/10;}return sum;}
}

9 219.存在重复元素II

219. 存在重复元素 II

已解答

简单

给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 ij ,满足 nums[i] == nums[j]abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false

示例 1:

输入:nums = [1,2,3,1], k = 3
输出:true

示例 2:

输入:nums = [1,0,1,1], k = 1
输出:true

示例 3:

输入:nums = [1,2,3,1,2,3], k = 2
输出:false

提示:

  • 1 <= nums.length <= 105
  • -109 <= nums[i] <= 109
  • 0 <= k <= 105

9.1 思路

hashmap的应用

    维护一个HashMap,map中是nums中的值->下标的映射遍历nums,假如在遍历时发现map中存储过该值,则根据map取出上次出现的下标,计算是否满足i-j<=k,若不满足,则将当前下标更新为j

9.2 代码

class Solution {public boolean containsNearbyDuplicate(int[] nums, int k) {/***/Map<Integer,Integer> map = new HashMap<>();for(int i=0;i<nums.length;i++){int num = nums[i];if(map.containsKey(num)){if(i-map.get(num)<=k){return true;}}map.put(num,i);}return false;}
}

10 128.最长连续序列

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例 1:

输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。

示例 2:

输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9

提示:

  • 0 <= nums.length <= 105
  • -109 <= nums[i] <= 109

10.1 思路

具体如下。重点是

  1. 需要找到可能的连续序列 开始的数字,之后往后遍历计算最长连续序列即可。
        利用hash表来存储nums的值,帮助枚举连续的数1.先遍历nums,将nums中的值都存在hashset中2.遍历hashset,找到每个可能的连续序列开始的数,然后从该数开始往后遍历,计算最长连续序列

10.2 代码

class Solution {public int longestConsecutive(int[] nums) {/***/Set<Integer> set = new HashSet<>();for(Integer num: nums){set.add(num);}int res = 0;for(Integer num: set){//2.1 判断是不是连续序列最开始的数if(set.contains(num-1)){continue;}//2.2 说明是连续序列最开始的数int curres = 0;while(set.contains(num++)){curres++;}res = Math.max(res,curres);}return res;}
}

相关文章:

【LeetCode 面试经典150题】详细题解之哈希表篇

【LeetCode 面试经典150题】详细题解之哈希表篇 1 哈希表的基础1.1 基础概念及实现1.2.1 哈希表的工作原理1.2.2 705.设计哈希集合1.2.3 706.设计哈希映射 1.2 HashMap相关1.2.1 基本操作1.2.2 遍历 1.3 Hashtable1.4 LinkedHashMap1.5 HashSet**1.5.1基本特性**1.5.2 基本方法…...

linux socket编程之udp_dict_serve服务端--引入配置文件

注意&#xff1a;本篇博客只是对上一篇博客功能的增加 1.创建配置文件(翻译) Dict.txt apple: 苹果 banana: 香蕉 cat: 猫 dog: 狗 book: 书 pen: 笔 happy: 快乐的 sad: 悲伤的 run: 跑 jump: 跳 teacher: 老师 student: 学生 car: 汽车 bus: 公交车 love: 爱 hate: 恨 hell…...

selenium学习笔记(二)

文章目录 前言设计模式POMPOM概念POM优势POM设计原则POM的实现 selenium的常用操作处理动态元素截图操作勾选复选框多层框架/窗口定位操作下拉框上传文件操作处理弹窗切换窗口拖拽操作 如何处理浏览器驱动更新导致的问题selenium与网站监控监听网页内容变化监控网络请求 seleni…...

宏集eX710物联网工控屏在石油开采机械中的应用与优势

案例概况 客户&#xff1a;天津某石油机械公司 应用产品&#xff1a;宏集eX710物联网工控屏 应用场景&#xff1a;钻井平台设备控制系统 一、应用背景 石油开采和生产过程复杂&#xff0c;涵盖钻井平台、采油设备、压缩机、分离器、管道输送系统等多种机械设备。这些设备通…...

linux——vi命令常用操作

一、vi模式 vi一般分为三种模式&#xff0c;分别是命令行模式、插入模式、末行模式 1.命令模式&#xff1a;控制屏幕光标的移动&#xff0c;按 &#xff1a;进入末行模式&#xff0c;按 i&#xff08;其他插入命令也可&#xff09; 进入插入模式&#xff1b; 2.插入模式&…...

vscode添加全局宏定义

利用vscode编辑代码时&#xff0c;设置了禁用非活动区域着色后&#xff0c;在一些编译脚本中配置的宏又识别不了 遇到#ifdef包住的代码就会变暗色&#xff0c;想查看代码不是很方便。如下图&#xff1a; 一 解决&#xff1a; 在vscode中添加全局宏定义。 二 步骤&#xff1a…...

重装荣耀X14笔记本电脑踩坑记

这几天趁着有国补搞了台荣耀 X14笔记本电脑。到手后第一件事情对我来说当然是要重装成Windows 11 LTSC版。所以按以往的经验做了个USB启动安装盘&#xff0c;但发现上电后按F12能进入启动设备选择&#xff0c;可是USB分类下没有任何设备。重启按F2进入设置界面&#xff0c;关闭…...

Android `android.graphics.drawable` 包深度解析:架构与设计模式

Android android.graphics.drawable 包深度解析:架构与设计模式 目录 引言Drawable 概述Drawable 的架构 Drawable 类层次结构Drawable 的核心方法Drawable 的设计模式 装饰者模式工厂模式状态模式常用 Drawable 子类解析 BitmapDrawableShapeDrawableLayerDrawableStateList…...

Kotlin语言的软件工程

Kotlin语言的软件工程 引言 在现代软件开发中&#xff0c;选择合适的编程语言是项目成功的关键之一。随着移动互联网的迅猛发展&#xff0c;以及大数据和人工智能等新兴技术的崛起&#xff0c;Kotlin语言凭借其简洁、高效和安全等特性&#xff0c;迅速崛起为备受欢迎的编程语…...

面试经典 150 题——数组/字符串(一)

文章目录 1、合并两个有序数组1.1 题目链接1.2 题目描述1.3 解题代码1.4 解题思路 2、移除元素2.1 题目链接2.2 题目描述2.3 解题代码2.4 解题思路 3、删除有序数组中的重复项3.1 题目链接3.2 题目描述3.3 解题代码3.4 解题思路 4、删除有序数组中的重复项 II4.1 题目链接4.2 题…...

使用亚马逊针对 PyTorch 和 MinIO 的 S3 连接器实现可迭代式数据集

2023 年 11 月&#xff0c;Amazon 宣布推出适用于 PyTorch 的 S3 连接器。适用于 PyTorch 的 Amazon S3 连接器提供了专为 S3 对象存储构建的 PyTorch 数据集基元&#xff08;数据集和数据加载器&#xff09;的实现。它支持用于随机数据访问模式的地图样式数据集和用于流式处理…...

TestMAX/DFT Compiler:时序单元的类型、连接顺序和后DFT优化

相关阅读 TestMAX/DFT Compilerhttps://blog.csdn.net/weixin_45791458/category_12865937.html?spm1001.2014.3001.5482 时序单元的状态 未映射的时序单元(Unmapped Sequential Cell) 在Design Compiler读取了一个RTL设计后&#xff0c;Design Compiler内置的HDL Compiler工…...

CAN201 Introduction to Networking(计算机网络)Pt.3 网络层

文章目录 4.Network Layter&#xff08;网络层&#xff09;4.1 Overview4.2 Router&#xff08;路由器&#xff09;4.3 Internet Protocol4.4 IPv4 addressing4.5 NAT&#xff08;network address translation&#xff0c;网路地址转换&#xff09;4.6 IPv64.7 Generalized For…...

App Factory:简化和加速私人应用开发

App Factory是Codigger提供的一套先进的开发工具、库和API&#xff0c;旨在帮助开发人员在现有的软件基础上添加特定的功能或扩展。它为私人应用的创建、开发和发布提供了一整套先进的工具集、集成的相关资源库以及强大的API接口&#xff0c;使开发者能够在现有的Codigger架构之…...

PHP语言laravel框架中基于Redis的异步队列使用实践与原理

在 Laravel 中&#xff0c;基于 Redis 的异步队列是通过 Laravel 的队列系统与 Redis 服务结合来实现的。这种队列机制允许你将任务推送到队列中&#xff0c;并由后台工作进程异步处理这些任务。这样&#xff0c;你就可以将耗时的操作&#xff08;如发送邮件、处理视频、数据同…...

全面Kafka监控方案:从配置到指标

文章目录 1.1.监控配置1.2.监控工具1.3.性能指标系统相关指标GC相关指标JVM相关指标Topic相关指标Broker相关指标 1.4.性能指标说明1.5.重要指标说明 1.1.监控配置 开启JMX服务端口&#xff1a;kafka基本分为broker、producer、consumer三个子项&#xff0c;每一项的启动都需要…...

kipotix4靶机实战

信息收集 1.判断靶机ip 原理&#xff1a;开靶机之前nmap扫一次网段&#xff0c;再开靶机之后扫一次&#xff0c;查看多出来的ip就是靶机ip ip192.168.98.1742.判断端口服务&#xff0c;系统版本 a.确定端口 b.-p指定端口进一步收集 c.信息筛选 1.端口&#xff1a;22,80,139,…...

我的秋招总结

我的秋招总结 个人背景 双非本&#xff0c;985硕&#xff0c;科班 准备情况 以求职为目的学习Java的时间大概一年。 八股&#xff0c;一开始主要是看B站黑马的八股文课程&#xff0c;背JavaGuide和小林coding还有面试鸭。 算法&#xff0c;250&#xff0c;刷了3遍左右 项目&…...

广义线性模型(GLM)全面解析

引言 广义线性模型&#xff08;Generalized Linear Model, GLM&#xff09;是统计学中一种重要的建模工具&#xff0c;它扩展了传统线性回归模型&#xff0c;能够处理响应变量的非正态分布和非线性关系。GLM 的灵活性和广泛的应用范围使其在金融、医学、社会科学等领域中成为数…...

C++ OCR 文字识别

一.引言 文字识别&#xff0c;也称为光学字符识别&#xff08;Optical Character Recognition, OCR&#xff09;&#xff0c;是一种将不同形式的文档&#xff08;如扫描的纸质文档、PDF文件或数字相机拍摄的图片&#xff09;中的文字转换成可编辑和可搜索的数据的技术。随着技…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...