【代码随想录】哈希表专栏(Java)
admin
2024-01-25 19:43:25
0

理论

哈希表是根据关键码的值而直接进行访问的数据结构。也称为散列表

数组就是一个哈希表。

需要快速判断一个元素是否出现在集合里面时,需要考虑使用哈希法。

有效的字母异位词 leetcode-242

/*** leetcode-242. 有效的字母异位词* @param s* @param t* @return*/
public boolean isAnagram(String s, String t) {int[] sArray = new int[26]; //默认是0for(char c : s.toCharArray()){sArray[c-'a']++;}for(char c : t.toCharArray()){sArray[c-'a']--;}for (int i = 0; i < sArray.length; i++) {if(sArray[i] != 0){ //若有元素不为0,则两者中每种字符的个数有差异,多或少return false;}}return true;
}

赎金信 leetcode-383

/*** leetcode-383 赎金信* @param ransomNote* @param magazine* @return*/
public boolean canConstruct(String ransomNote, String magazine) {int[] ransomArray = new int[26]; //默认是0for(char c : ransomNote.toCharArray()){ransomArray[c-'a']++;}for(char c : magazine.toCharArray()){if(ransomArray[c-'a'] != 0){ //只统计ransom中有的字母ransomArray[c-'a']--;}}for (int i = 0; i < ransomArray.length; i++) {if(ransomArray[i] != 0){return false;}}return true;
}

字母异位词分组 leetcode-49

/*** 字母异位词分组* @param strs* @return*/
public List> groupAnagrams(String[] strs) {Map> map = new HashMap>();for (String str : strs) {char[] cArray = str.toCharArray();Arrays.sort(cArray); //给字符数组排序(位置虽然不同,但排序后一定是相同的)String key = new String(cArray);List list = map.getOrDefault(key, new ArrayList());list.add(str);map.put(key,list); //java中的map在键相同时会直接抵消}return new ArrayList>(map.values());
}

找到字符串中所有字母异位词 leetcode-438

方法1:

/*** 438. 找到字符串中所有字母异位词* (易于理解,但时间复杂度高)** @param s* @param p* @return*/
public List findAnagrams(String s, String p) {char[] sArray = s.toCharArray();char[] pArray = p.toCharArray();int[] charArray = new int[26];for (char c : pArray) {charArray[c - 'a']++;}List list = new ArrayList<>();for (int i = 0; i < sArray.length; i++) {if (i > sArray.length - pArray.length) break;int temp[] = Arrays.copyOf(charArray, charArray.length); //数组是对象,不能直接赋值boolean flag = true;for (int j = i; j < i + pArray.length; j++) {temp[sArray[j] - 'a']--;}for (int k = 0; k < temp.length; k++) {if (temp[k] != 0) {flag = false;}}if (flag) list.add(i);}return list;
}

方法2:滑动窗口

/*** 438. 找到字符串中所有字母异位词* 滑动窗口* 时间 9 ms击败 61.47%* @param s* @param p* @return*/
public List findAnagrams2(String s, String p) {int sLen = s.length();int pLen = p.length();if (sLen < pLen) return new ArrayList<>();int[] needs = new int[26];int[] window = new int[26];for (char c : p.toCharArray()) {needs[c - 'a']++;}int count = 0;for (int i = 0; i < needs.length; i++) { //统计needs的实际大小 例如“aa”,实际大小为1if (needs[i] != 0) count++;}List list = new ArrayList<>();int left = 0, right = 0, valid = 0;while (right < s.length()) {char c = s.charAt(right);right++;if (needs[c - 'a'] != 0) {window[c - 'a']++;if (window[c - 'a'] == needs[c - 'a']) {valid++;}}if (right - left == p.length()) {if (valid == count) {list.add(left);}char d = s.charAt(left);left++;if (needs[d - 'a'] > 0) {if (window[d - 'a'] == needs[d - 'a']) {valid--;}window[d - 'a']--;}}}return list;
}

方法3:速度最快,完全匹配(顺序不考虑),窗口大小固定,个人认为这种方法更好理解

/*** 438. 找到字符串中所有字母异位词* 把窗口大小固定更易于理解** @param s* @param p* @return*/
public List findAnagrams3(String s, String p) {int sLen = s.length();int pLen = p.length();if (sLen < pLen) return new ArrayList<>();int[] needs = new int[26];int[] window = new int[26];for (int i = 0; i < pLen; i++) {needs[p.charAt(i)-'a']++;window[s.charAt(i)-'a']++;}List list = new ArrayList<>();int left = 0, right = pLen - 1;if (Arrays.equals(needs, window)) list.add(0); //可能0下标就相同while (right < sLen-1) { //下面right往后移动,这里要减1,不然下面数组越界//右边界往后移right++;window[s.charAt(right) - 'a']++;//左边界往后移window[s.charAt(left) - 'a']--;left++;if (Arrays.equals(needs, window)) {list.add(left);}}return list;
}

两个数组的交集 leetcode-349

方法1:

/*** 349. 两个数组的交集* 时间* 1 ms* 击败* 98.73%* @param nums1* @param nums2* @return*/
public int[] intersection(int[] nums1, int[] nums2) {int[] arr2 = new int[1000];int[] ans = new int[1000];for (int i : nums2) {arr2[i]++;}int size = 0;for (int i = 0; i < nums1.length; i++) {if(arr2[nums1[i]] != 0 && ans[nums1[i]] ==0){ans[nums1[i]]++;size++;}}int[] res = new int[size];int index = 0;for (int i = 0; i < ans.length; i++) {if(ans[i]!=0){res[index++]=i;}}return res;
}

方法2:

/*** 时间* 0 ms* 击败* 100%* @param nums1* @param nums2* @return*/
public int[] intersection2(int[] nums1, int[] nums2) {int[] map = new int[1000];List list = new ArrayList<>(); //因为不知道结果数组有多大,所以先用list存for (int i : nums1) {map[i]++;}for (int i : nums2) {if(map[i] != 0){list.add(i);map[i] = 0;  //删除索引,防止有相同元素时,重复添加}}int[] ans = new int[list.size()];for (int i = 0; i < list.size(); i++) {ans[i] = list.get(i);}return ans;
}

两个数组的交集 II leetcode-350

/**** 时间* 0 ms* 击败* 100%* 350. 两个数组的交集 II 与上一题相比,该题可以统计重复的,但是两个数组中元素重复的次数不一样时,取小* @param nums1* @param nums2* @return*/
public int[] intersect(int[] nums1, int[] nums2) {int[] map = new int[1001];for (int i : nums1) {map[i]++;}int[] ans = new int[Math.max(nums1.length, nums2.length)];int j = 0;for (int i : nums2) {if(map[i] > 0){ans[j++] = i;map[i]--;  //索引减1}}return Arrays.copyOfRange(ans, 0, j);
}

快乐数 leetcode-202

方法1:

/*** 202 快乐数* 用时1ms* @param n* @return*/
public boolean isHappy(int n){Set set = new HashSet<>();while ( n!=1 && !set.contains(n)){set.add(n);n = nextNum(n);}return n==1;
}
public int nextNum(int n){int sum = 0;while (n > 0){int temp = n%10;sum+=temp*temp;n=n/10;}return sum;
}

方法2:

public boolean isHappy2(int n){int slow = n,fast = n; //类比于链表找环,设置快慢指针do{slow = nextNum(slow);fast = nextNum(fast);fast = nextNum(fast);}while (slow != fast);return slow  == 1;
}

两数之和 leetcode-1

/*** 两数之和 leetcode-1* @param nums* @param target* @return*/
public int[] twoSum(int[] nums, int target) {Map map = new HashMap<>();int[] res = new int[2];int i;for (i = 0; i < nums.length; i++) {int temp = target - nums[i];if (!map.containsKey(temp)) {map.put(nums[i], i);} else {res[0] = i;res[1] = map.get(temp);break;}}return res;
}

四数相加II leetcode-454

/*** 四数相加* @param nums1* @param nums2* @param nums3* @param nums4* @return*/
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {Map map1 = new HashMap<>();for (int i : nums1) {for (int j : nums2) {map1.put(i+j,map1.getOrDefault(i+j,0)+1); //统计任意两个数和的次数}}int count = 0;for (int i : nums3) {for (int j : nums4) {int temp = 0-(i+j);if(map1.containsKey(0-(i+j))){count+=map1.get(0-(i+j));}}}return count;
}

三数之和 leetcode-15

/*** 三数之和 leetcode-15* @param nums* @return*/
public List> threeSum(int nums[]) {List> res = new ArrayList<>();Arrays.sort(nums);for (int i = 0; i < nums.length; i++) {if (nums[i] > 0) return res;if (i >0 && nums[i] == nums[i - 1]) continue; //去重int left = i+1,right = nums.length-1;while (left < right) {int sum = nums[i] + nums[left] + nums[right];if(sum >0){right--;} else if (sum < 0) {left++;}else{res.add(Arrays.asList(nums[i],nums[left],nums[right]));while (left left++;}while (left right--;}right--;left++;}}}return res;
}

四数之和 leetcode-18

public List> fourSum(int[] nums, int target) {List> list = new ArrayList<>();Arrays.sort(nums);for (int i = 0; i < nums.length - 3; i++) {if (nums[i] > 0 && nums[i] > target) {return list;}if (i > 0 && nums[i] == nums[i - 1]) {continue;  //去重}for (int j = i + 1; j < nums.length - 2; j++) {if (j > i + 1 && nums[j] == nums[j - 1]) {continue; // 超过i+1才属于j的部分}int left = j + 1, right = nums.length - 1;while (left < right) {int sum = nums[i] + nums[j] + nums[left] + nums[right];if (sum < target) {left++;} else if (sum > target) {right--;} else {list.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));left++;while (left < right && nums[left] == nums[left - 1]) {left++;}right--;while (left < right && nums[right] == nums[right + 1]) {right--;}}}}}return list;
}

相关内容

热门资讯

安卓系统不推送更新,揭秘背后的... 最近是不是发现你的安卓手机有点儿“懒”啊?更新推送总是慢吞吞的,让人等得花儿都谢了。别急,今天就来给...
ape格式转换安卓系统,享受音... 你有没有想过,你的安卓手机里的ape格式音乐文件,竟然可以通过一个小小的转换,焕发出全新的生命力?没...
获取安卓系统加载器,核心功能与... 你有没有想过,你的安卓手机里那些神奇的软件和游戏是怎么被安装到你的设备上的呢?没错,就是通过一个叫做...
安卓系统文件夹在哪,安卓系统文... 你有没有遇到过这样的情况:手机里乱糟糟的,想找个文件却找不到?别急,今天就来给你揭秘安卓系统文件夹的...
安卓手感最好的裸机系统,安卓手... 安卓手感最好的裸机系统:探索极致体验的秘密武器在数字世界中,我们常常被各种功能和复杂操作所包围,尤其...
nas如何刷回安卓系统,轻松刷... 你有没有想过,你的NAS(网络附加存储)突然间变成了一个安卓的小天地?别急,这可不是什么天方夜谭,而...
荣耀沿用的安卓系统吗,打造个性... 你有没有注意到,最近荣耀的新机发布,大家都在热议一个问题:荣耀沿用的安卓系统吗?这可是个让人好奇不已...
快麦erp系统安卓下载,一键下... 你有没有听说最近一款叫做快麦ERP系统的软件在安卓平台上大受欢迎呢?没错,就是那个能让你企业管理如虎...
华为安卓系统下载app,一步到... 你有没有发现,最近华为手机的用户们都在忙活一件大事儿?没错,那就是下载安卓系统上的各种app啦!这可...
原生安卓系统游戏模式,畅享沉浸... 亲爱的手机游戏爱好者们,你是否曾为手机游戏运行不畅而烦恼?又或者,你是否渴望在游戏中获得更极致的体验...
安卓9改系统语言设置,轻松切换... 你有没有发现,手机里的语言设置有时候真的让人头疼?比如说,你突然想用一下安卓9的系统语言设置,结果发...
怎么升级安卓最新系统,畅享安卓... 亲爱的手机控们,你是不是也和我一样,对安卓系统的更新充满了期待?每次系统升级,都仿佛给我们的手机带来...
安卓系统电视跳舞毯,家庭娱乐新... 你有没有想过,家里的电视除了用来追剧、看电影,还能变成一个充满活力的娱乐中心?没错,我要给你介绍的就...
安卓系统维护周期,全方位守护您... 亲爱的手机控们,你是不是也和我一样,对安卓系统的维护周期充满了好奇呢?毕竟,我们的手机可是我们日常生...
安卓系统电脑怎么往下滑,一扫即... 你有没有发现,用安卓系统电脑的时候,有时候屏幕上会出现一些小图标或者应用,你想要快速浏览或者切换,却...
手机中判断安卓系统苹果系统js... 你有没有想过,你的手机里到底装的是安卓系统还是苹果系统呢?这可不是一个小问题哦,因为不同的系统,就像...
window系统和安卓系统还原... 你有没有遇到过手机或电脑突然卡顿,或者不小心删掉了重要的文件?别急,今天就来给你详细说说如何让win...
安卓系统打电话变声器,轻松实现... 安卓系统打电话变声器:探索数字时代的通信革新在数字化浪潮中,智能手机已经成为我们生活中不可或缺的一部...
android系统和安卓哪个好... 说到手机操作系统,你是不是也和我一样,对Android系统和安卓系统傻傻分不清楚呢?别急,今天就来给...
米柚系统是不是安卓,基于安卓的... 亲爱的读者,你是否曾在手机的选择上犹豫不决,尤其是当面对那些自称是安卓系统但又有自己特色的操作系统时...