【代码随想录】哈希表专栏(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;
}

相关内容

热门资讯

电视安卓系统哪个品牌好,哪家品... 你有没有想过,家里的电视是不是该升级换代了呢?现在市面上电视品牌琳琅满目,各种操作系统也是让人眼花缭...
安卓会员管理系统怎么用,提升服... 你有没有想过,手机里那些你爱不释手的APP,背后其实有个强大的会员管理系统在默默支持呢?没错,就是那...
安卓系统软件使用技巧,解锁软件... 你有没有发现,用安卓手机的时候,总有一些小技巧能让你玩得更溜?别小看了这些小细节,它们可是能让你的手...
安卓系统提示音替换 你知道吗?手机里那个时不时响起的提示音,有时候真的能让人心情大好,有时候又让人抓狂不已。今天,就让我...
安卓开机不了系统更新 手机突然开不了机,系统更新还卡在那里,这可真是让人头疼的问题啊!你是不是也遇到了这种情况?别急,今天...
安卓系统中微信视频,安卓系统下... 你有没有发现,现在用手机聊天,视频通话简直成了标配!尤其是咱们安卓系统的小伙伴们,微信视频功能更是用...
安卓系统是服务器,服务器端的智... 你知道吗?在科技的世界里,安卓系统可是个超级明星呢!它不仅仅是个手机操作系统,竟然还能成为服务器的得...
pc电脑安卓系统下载软件,轻松... 你有没有想过,你的PC电脑上安装了安卓系统,是不是瞬间觉得世界都大不一样了呢?没错,就是那种“一机在...
电影院购票系统安卓,便捷观影新... 你有没有想过,在繁忙的生活中,一部好电影就像是一剂强心针,能瞬间让你放松心情?而我今天要和你分享的,...
安卓系统可以写程序? 你有没有想过,安卓系统竟然也能写程序呢?没错,你没听错!这个我们日常使用的智能手机操作系统,竟然有着...
安卓系统架构书籍推荐,权威书籍... 你有没有想过,想要深入了解安卓系统架构,却不知道从何下手?别急,今天我就要给你推荐几本超级实用的书籍...
安卓系统看到的炸弹,技术解析与... 安卓系统看到的炸弹——揭秘手机中的隐形威胁在数字化时代,智能手机已经成为我们生活中不可或缺的一部分。...
鸿蒙系统有安卓文件,畅享多平台... 你知道吗?最近在科技圈里,有个大新闻可是闹得沸沸扬扬的,那就是鸿蒙系统竟然有了安卓文件!是不是觉得有...
宝马安卓车机系统切换,驾驭未来... 你有没有发现,现在的汽车越来越智能了?尤其是那些豪华品牌,比如宝马,它们的内饰里那个大屏幕,简直就像...
p30退回安卓系统 你有没有听说最近P30的用户们都在忙活一件大事?没错,就是他们的手机要退回安卓系统啦!这可不是一个简...
oppoa57安卓原生系统,原... 你有没有发现,最近OPPO A57这款手机在安卓原生系统上的表现真是让人眼前一亮呢?今天,就让我带你...
安卓系统输入法联想,安卓系统输... 你有没有发现,手机上的输入法真的是个神奇的小助手呢?尤其是安卓系统的输入法,简直就是智能生活的点睛之...
怎么进入安卓刷机系统,安卓刷机... 亲爱的手机控们,你是否曾对安卓手机的刷机系统充满好奇?想要解锁手机潜能,体验全新的系统魅力?别急,今...
安卓系统程序有病毒 你知道吗?在这个数字化时代,手机已经成了我们生活中不可或缺的好伙伴。但是,你知道吗?即使是安卓系统,...
奥迪中控安卓系统下载,畅享智能... 你有没有发现,现在汽车的中控系统越来越智能了?尤其是奥迪这种豪华品牌,他们的中控系统简直就是科技与艺...