提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
一般来说哈希表都是用来快速判断一个元素是否出现集合里。
一、力扣242. 有效的字母异位词
两个字符串,里面全是小写字母,直接用数组计数之后比较就行
class Solution {
public boolean isAnagram(String s, String t) {
int[] arr = new int[27];
for(char c : s.toCharArray()){
arr[c - 'a'] ++;
}
for(char c : t.toCharArray()){
arr[c - 'a'] --;
}
for(int a : arr){
if(a != 0){
return false;
}
}
return true;
}
}
二、力扣383. 赎金信
两个字符串,都是由小写字母构成的,判断其中一个是否可以由另外一个构成,直接数组一个++计数,一个--计数,最后计数数组里面有小于0的就表示失败,否则成功
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
int[] arr = new int[27];
for(char c : magazine.toCharArray()){
arr[c - 'a'] ++;
}
for(char c : ransomNote.toCharArray()){
arr[c - 'a'] --;
}
for(int a : arr){
if(a < 0){
return false;
}
}
return true;
}
}
三、力扣49. 字母异位词分组
一个字符串集合,把里面所有的异位词进行分组,很明显需要哈希表,先重新构建key值,同一组异位词是同一个key,直接用字母拼上字母的个数就行,然后用map收集,最后输出
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> res = new ArrayList<>();
Map<String,List<String>> map = new HashMap<>();
for(String str : strs){
int[] arr = new int[27];
for(char c : str.toCharArray()){
arr[c - 'a'] ++;
}
String s = "";
for(int i = 0; i < 26; i ++){
if(arr[i] != 0){
s += ('a' + i);
s += arr[i];
}
}
List<String> list = map.getOrDefault(s, new ArrayList<String>());
list.add(str);
map.put(s, list);
}
return map.values().stream().collect(Collectors.toList());
}
}
四、力扣438. 找到字符串中所有字母异位词
找到字符串中的所有字母异位词,先把目标异位词收集进数组,之后,被处理字符串,使用双指针滑动窗口进行处理,窗口大小就是目标异位词的长度,每次移动一下,就更新,另外一个收集数组,更新完之后,两个收集数组进行比对,若是一致,就把左指针下标收集进最终返回的list中
class Solution {
public List<Integer> findAnagrams(String s, String p) {
List<Integer> res = new ArrayList<>();
if(s.length() < p.length()){
return res;
}
int[] arr1 = new int[26];
int[] arr2 = new int[26];
for(int i = 0; i < p.length(); i ++){
arr1[p.charAt(i) - 'a'] ++;
arr2[s.charAt(i) - 'a'] ++;
}
int left = 0, right = p.length()-1;
while(right < s.length()){
boolean flag = true;
for(int i = 0; i < 26; i ++){
if(arr1[i] != arr2[i]){
flag = false;
}
}
if(flag){
res.add(left);
}
right ++;
if(right >= s.length()){
break;
}
arr2[s.charAt(left) - 'a'] --;
arr2[s.charAt(right) - 'a'] ++;
left ++;
}
return res;
}
}
五、力扣349. 两个数组的交集
求两个数组的交集,直接创建两个set,先用第一个set收集第一个数组,之后,判断第二个数组中的每一个元素是否存在第一个set中,若是,就收集到第二个set中,最后把第二个set作为最终结果
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
Set<Integer> set1 = new HashSet<>();
for(int a : nums1){
set1.add(a);
}
Set<Integer> set2 = new HashSet<>();
for(int a : nums2){
if(set1.contains(a)){
set2.add(a);
}
}
int[] res = new int[set2.size()];
int i = 0;
for(int a : set2){
res[i ++] = a;
}
return res;
}
}
六、力扣350. 两个数组的交集 II
使用两个map分别收集
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
Map<Integer,Integer> map1 = new HashMap<>();
Map<Integer,Integer> map2 = new HashMap<>();
for(int a : nums1){
map1.put(a, map1.getOrDefault(a,0) + 1);
}
for(int a : nums2){
if(map2.getOrDefault(a,0) < map1.getOrDefault(a,0)){
map2.put(a, map2.getOrDefault(a,0)+1);
}
}
List<Integer> list = new ArrayList<>();
for(Map.Entry<Integer,Integer> entry : map2.entrySet()){
for(int a = 0; a < entry.getValue(); a ++){
list.add(entry.getKey());
}
}
int[] res = new int[list.size()];
for(int i = 0; i < res.length; i ++){
res[i] = list.get(i);
}
return res;
}
}
七、力扣202. 快乐数
读题要仔细,快乐数的定义是,一个正整数,对于每一个位置上的数都进行平方,然后求和,得到新的数重复这个过程,最后得到的结果,要么为1,要么无限循环,只有这两个结果,换句话说,一定会出现重复的结果,用一个set判断中条件,最后判断是否为1
class Solution {
public boolean isHappy(int n) {
Set<Integer> set = new HashSet<>();
while(!set.contains(n)){
set.add(n);
n = fun(n);
}
return n == 1;
}
public int fun(int n){
int sum = 0;
while(n != 0){
int t = n % 10;
n /= 10;
sum += (t * t);
}
return sum;
}
}
八、力扣1. 两数之和
给定一个数组,从中寻找目标值的下标
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
int[] res = new int[2];
for(int i = 0; i < nums.length; i ++){
map.put(nums[i], i);
}
for(int i = 0; i < nums.length; i ++){
int temp = target - nums[i];
if(map.containsKey(temp) && map.get(temp) != i){
res[0] = i;
res[1] = map.get(temp);
break;
}
}
return res;
}
}
九、力扣454. 四数相加 II
这道题目是4个数组,不需要考虑重复问题,直接map就能做,累加求和就是
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
int res = 0;
Map<Integer, Integer> map = new HashMap<>();
for(int a : nums1){
for(int b : nums2){
map.put((a+b), map.getOrDefault((a+b), 0) + 1);
}
}
for(int a : nums3){
for(int b : nums4){
int temp = -(a+b);
if(map.containsKey(temp)){
res += map.get(temp);
}
}
}
return res;
}
}
十、力扣15. 三数之和
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> res = new ArrayList<>();
for(int i = 0; i < nums.length-2; ){
int left = i+1, right = nums.length-1;
while(left < right){
int sum = nums[i] + nums[left] + nums[right];
if(sum == 0){
List<Integer> list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[left]);
list.add(nums[right]);
res.add(list);
left ++;
while(left < right && nums[left-1] == nums[left]){
left ++;
}
}else if(sum > 0){
right --;
while(left < right && nums[right+1] == nums[right]){
right --;
}
}else{
left ++;
while(left < right && nums[left-1] == nums[left]){
left ++;
}
}
}
i ++;
while(i < nums.length-2 && nums[i-1] == nums[i]){
i ++;
}
}
return res;
}
}
十一、力扣18. 四数之和
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> res = new ArrayList<>();
if(nums.length < 4){
return res;
}
Arrays.sort(nums);
if(target < 0 && nums[0] > 0){
return res;
}
for(int i = 0; i < nums.length-3; i++){
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-1] == nums[j]){
continue;
}
int left = j+1, right = nums.length-1;
while(left < right){
int sum = nums[i] + nums[j] + nums[left] + nums[right];
if(sum > target){
right --;
}else if(sum < target){
left ++;
}else{
res.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
right --;
while(left < right && nums[right+1] == nums[right]){
right --;
}
left ++;
while(left < right && nums[left-1] == nums[left]){
left ++;
}
}
}
}
}
return res;
}
}