昨天周天休息日,本来是想回顾一下学到的知识,写一篇总结性质的博客。但偶感风寒,状态欠佳;先进行第三章 哈希表的学习吧!代码随想录 (programmercarl.com)
什么时候想到用哈希法: 当遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法 。
242. 有效的字母异位词
记录一下Java遍历字符串的几种方法:
①:charAt()
- length():返回此字符序列的长度。
- charAt(int index):返回指定索引处的char值。
那么我们就可以通过for循环遍历字符串从0到length-1的每一个字符。
②:toCharArray()
- toCharArray():将此字符串转换为字符数组。
这样就可以将字符串先转换成字符数组,然后再用for循环遍历数组即可。
③:使用substring(i ,i+1)
- CharSequence subSequence( int beginIndex, int endIndex):返回一个字符序列,该序列是该序列的子序列。
所以就可以通过把beginIndex设定为i,而endIndex设定为i+1,这样每次也是获得一个字符。
注:for循环可以使用for(char a : str.toCharArray())
class Solution {
public boolean isAnagram(String s, String t) {
int[] nums = new int[26];
for (int i = 0; i < s.length(); i++) {
nums[s.charAt(i) - 'a']++;
}
for (int i = 0; i < t.length(); i++) {
nums[t.charAt(i) - 'a']--;
}
for(int i=0; i<26;i++){
if(nums[i] != 0){
return false;
}
}
return true;
}
}
349. 两个数组的交集
记录一下 Java 将set<int>转为int数组的方法:(其中resSet为结果集合)
resSet.stream().mapToInt(x -> x).toArray();
另一种方法:
int [] res = new int [set2.size()]; int index = 0; for(int num : set2){ res[index++] = num; } return res;
建议:本题就开始考虑 什么时候用set 什么时候用数组,本题其实是使用set的好题,但是后来力扣改了题目描述和 测试用例,添加了 0 <= nums1[i], nums2[i] <= 1000 条件,所以使用数组也可以了。
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
HashSet<Integer> set1 = new HashSet<Integer>();
HashSet<Integer> set2 = new HashSet<Integer>();
for(int num : nums1){
set1.add(num);
}
for(int num : nums2){
if(set1.contains(num)){
set2.add(num);
}
}
int [] res = new int [set2.size()];
int index = 0;
for(int num : set2){
res[index++] = num;
}
return res;
}
}
小结:有:元素不重复、需判断某元素是否出现在集合中 应想到使用set。
202. 快乐数
题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!
当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了。
所以这道题目使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。
判断sum是否重复出现就可以使用HashSet。
class Solution {
public boolean isHappy(int n) {
HashSet<Long> set = new HashSet<Long>();
long temp = n;
while(getRes(temp) != 1){
temp = getRes(temp);
if(!set.contains(temp)){
set.add(temp);
}
else{
return false;
}
}
return true;
}
public long getRes(long n){
long sum = 0;
while(n / 10 > 0){
sum += (n%10)*(n%10);
n /= 10;
}
sum += n*n;
return sum;
}
}
1.两数之和
暴力解法
class Solution {
public int[] twoSum(int[] nums, int target) {
int temp = 0;
int [] res = new int[2];
for(int i=0; i<nums.length; i++){
temp = target - nums[i];
for(int j = 0; j<nums.length; j++){
if(i != j && nums[j] == temp)
{
res[0] = i;
res[1] = j;
return res;
}
}
}
return null;
}
}
时间复杂度O(n^2) 空间复杂度O(1)
尝试使用HashMap:无思路,看题解。代码随想录
本题其实有四个重点:
- 为什么会想到用哈希表
- 哈希表为什么用map
- 本题map是用来存什么的
- map中的key和value用来存什么的
把这四点想清楚了,本题才算是理解透彻了。
哈希解法
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer,Integer> hs = new HashMap<>();
int temp = 0;
for(int i=0; i<nums.length; i++){
temp = target - nums[i];
if(hs.containsKey(temp)){
return new int[]{i,hs.get(temp)};
}
hs.put(nums[i],i);
}
return null;
}
}