本文将重点解析 LeetCode 热题100 中关于哈希和双指针的题目,帮助读者更好地理解和掌握这两种算法思想。
哈希表专题
- 两数之和
题目描述:给定一个整数数组和一个目标值,找出数组中 和 为目标值的两个数的下标。
上来的想法,想想人脑怎么着找。无非就是两层循环,那肯定有重复找的数的呀。我知道A他的天选就是B,那我不妨就把在找A的时候看看B好了,也省的非要凑齐A+B.
解题思路:这是一道典型的哈希表应用题目。我们可以遍历数组,对于每个元素,计算目标值与当前元素的差值,然后检查这个差值是否存在于已经遍历过的元素中。如果存在,那么我们就找到了一对和为目标值的数。
public int[] twoSum(int[] nums,int k){Map<Integer,Integer> map=new Hashmap<>();//题目让返回的是下标for(int i=0;i<nums.size();i++){if(map.containsKey(k-nums[i])){return new int[]{i,map.get(k-nums[i])};}map.put(nums[i],i);}return new int[]{-1,-1};
}
个人碎碎念:这道题也算是leetcode 热题100里面的 abandon了,我每次都从这个开始。也都abandon了。
- 字母异位词分组
题目描述:给定一个字符串数组,将字母异位词的字符串分组在一起。
异构词是什么, abc cba cab 《-这些就是异构词,它们构成的元素都是一样的,排列不同罢了。那就把他们打成一样的状态
解题思路:这个问题可以通过哈希表来解决。我们可以遍历每个字符串,计算它的字母频率(例如,‘a’ 出现的次数、‘b’ 出现的次数等),然后将这个频率作为键值存储在哈希表中。接着,对于每个新的字符串,我们检查它的字母频率是否已经存在于哈希表中,如果存在,就将它添加到对应的列表中。
伪代码
维护答案数组
遍历字符串数组
统计字符串次数 得到map
现在是以abc开头的,所以先往答案数组压入abc
之后根据abc的map进行判断,那些可以跟在abc的数组里面
如果他们统计次数都是和map里面的匹配,ok,加进去,然后从原来的数组里面remove掉。
java
public List<List> solution(String[] strs){
List<List> ans=new ArrayList<>();
维护这个结果,就考虑什么时候加就行了
那肯定是有元素和前面这个元素构成一样了呀,-》构成怎么表示-》hashmap
for(String str:strs){
HashMap<Character,Integer> map=new HashMap<>();
for(char c:str.toCharArray()){
map.put(c,map.getOrDefault(c,0)+1);
}
List tmp=new ArrayList<>();
tmp.add(str);
strs.remove(str);
for(String sameStr:strs){
写不下去了
}
}
}
上面是我错误思路下的产物。
我这里的错误就是没搞明白,hashmap保存的要是什么。
比较两个字符串元素,除了把他们拆开比较,一个一个存到map里面,一个个比较。还可以把他们排序之后equal比较。
其实在上面自己死胡同思路那里,就觉得hashmap应该是一个list,总不能用一个清空一个,那这后面的元素还怎么参考。
public List<List<String>> solution(String[] strs){Map<String,List<String>> map=new HashMap<>();for(String str:strs){//HashMap<Character,Integer> map=new HashMap<>();char[] array=str.toCharArray();Array.sort(array);String a=new String(array);if(!map.containsKey(a)){List<String> tmp=new ArrayList<>();tmp.add(str);map.put(a,tmp);}else{map.get(a).add(str);}}return new ArrayList<>(map.values());
}
双指针专题
- 移动零
题目描述:给定一个数组,将所有 0 移动到数组的末尾,保持非零元素的相对顺序。
解题思路:这是一个经典的双指针问题。我们可以使用两个指针,一个指针遍历数组,另一个指针指向当前非零元素的位置。当我们遇到非零元素时,就将它与指针指向的位置交换,然后移动指针。
- 盛最多水的容器
题目描述:给定一个由非负整数表示的数组,用来表示容器的宽度和高度。计算由这些容器组成的堤坝能盛多少水。
解题思路:这个问题可以通过双指针来解决。我们维护两个指针,一个在数组的开始,另一个在数组的末尾。这两个指针代表堤坝的两端。我们计算由这两个指针形成的堤坝能盛多少水,然后移动能形成更大堤坝的一端的指针。
- 三数之和
题目描述:给定一个包含 n 个数字的数组,找出所有三元组,使得这些数的和为 0。
解题思路:虽然这个问题看起来需要三重循环,但实际上可以通过双指针技术来优化。首先对数组进行排序,然后遍历数组,对于每个元素,我们使用两个指针分别指向当前元素的左右两侧,尝试找到和为 0 的三元组。
- 接雨水
题目描述:给定 n 个非负整数,用以表示房屋的高度。如果雨水从上到下落下来,计算雨水能接多少。
解题思路:这个问题可以通过双指针和动态规划的结合来解决。我们维护一个数组来保存每个位置左边和右边的最高条形块。然后遍历原数组,计算每个位置能接的雨水量,即当前位置的房屋高度与左右两边最高条形块中的较小者之差。