242. 有效的字母异位词

https://leetcode-cn.com/problems/valid-anagram/

  1. public boolean isAnagram(String s, String t) {
  2. char[] schar = s.toCharArray();
  3. char[] tchar = t.toCharArray();
  4. if (s.length() != t.length()) return false;
  5. int[] count = new int[26];
  6. for (int i = 0; i < schar.length; i++) {
  7. count[schar[i] - 'a']++;
  8. }
  9. for (int i = 0; i < tchar.length; i++) {
  10. if (--count[tchar[i] - 'a'] < 0) {
  11. return false;
  12. }
  13. }
  14. return true;
  15. }

383. 赎金信

https://leetcode-cn.com/problems/ransom-note/

  1. public boolean canConstruct(String ransomNote, String magazine) {
  2. char[] str1 = ransomNote.toCharArray();
  3. char[] str2 = magazine.toCharArray();
  4. int[] count = new int[26];
  5. for (int i = 0; i < str2.length; i++) {
  6. count[str2[i] - 'a']++;
  7. }
  8. for (int i = 0; i < str1.length; i++) {
  9. count[str1[i] - 'a']--;
  10. }
  11. for (int i : count) {
  12. if (i < 0) {
  13. return false;
  14. }
  15. }
  16. return true;
  17. }

49. 字母异位词分组

https://leetcode-cn.com/problems/group-anagrams/

  • 排序

由于互为字母异位词的两个字符串包含的字母相同,因此对两个字符串分别进行排序之后得到的字符串一定是相同的,故可以将排序之后的字符串作为哈希表的键

  1. public List<List<String>> groupAnagrams(String[] strs) {
  2. Map<String, List<String>> map = new HashMap<>();
  3. for (String str : strs) {
  4. char[] chs = str.toCharArray();
  5. Arrays.sort(chs);
  6. String key = String.valueOf(chs);
  7. if (!map.containsKey(key)) {
  8. map.put(key, new ArrayList<>());
  9. }
  10. map.get(key).add(str);
  11. }
  12. List<List<String>> res = new ArrayList<>();
  13. for (List<String> list : map.values()) {
  14. res.add(list);
  15. }
  16. return res;
  17. }

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

https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/

  • 滑动窗口 + 欠帐表 + 总账目

https://www.yuque.com/docs/share/38e3c359-548d-4304-be67-dab91724041a?#

  1. public List<Integer> findAnagrams(String s, String p) {
  2. List<Integer> ans = new ArrayList<>();
  3. if (s == null || p == null || s.length() < p.length()) {
  4. return ans;
  5. }
  6. char[] str = s.toCharArray();
  7. char[] ptr = p.toCharArray();
  8. int N = str.length;
  9. int M = ptr.length;
  10. // 欠帐表
  11. Map<Character, Integer> map = new HashMap<>();
  12. // 总账目
  13. int all = M;
  14. // 欠帐表初始化
  15. for (char c : ptr) {
  16. if (map.containsKey(c)) {
  17. map.put(c, map.get(c) + 1);
  18. } else {
  19. map.put(c, 1);
  20. }
  21. }
  22. for (int i = 0; i < M - 1; i++) {
  23. if (map.containsKey(str[i])) {
  24. int count = map.get(str[i]);
  25. map.put(str[i], count - 1);
  26. if (count > 0) {
  27. all--;
  28. }
  29. }
  30. }
  31. for (int end = M - 1, start = 0; end < N; end++, start++) {
  32. if (map.containsKey(str[end])) {
  33. int count = map.get(str[end]);
  34. map.put(str[end], count - 1);
  35. if (count > 0) {
  36. all--;
  37. }
  38. }
  39. if (all == 0) {
  40. ans.add(start);
  41. }
  42. if (map.containsKey(str[start])) {
  43. int count = map.get(str[start]);
  44. map.put(str[start], count + 1);
  45. if (count >= 0) {
  46. all++;
  47. }
  48. }
  49. }
  50. return ans;
  51. }

349. 两个数组的交集

  1. public int[] intersection(int[] nums1, int[] nums2) {
  2. Set<Integer> set = new HashSet();
  3. Set<Integer> set1 = new HashSet();
  4. for (int i : nums1) {
  5. set.add(i);
  6. }
  7. for (int i : nums2) {
  8. if (set.contains(i)) {
  9. set1.add(i);
  10. }
  11. }
  12. int[] ans = new int[set1.size()];
  13. int index = 0;
  14. for (int i : set1) {
  15. ans[index++] = i;
  16. }
  17. return ans;
  18. }

350. 两个数组的交集Ⅱ

https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/

  1. public int[] intersect(int[] nums1, int[] nums2) {
  2. Map<Integer, Integer> map = new HashMap<>();
  3. for (int i : nums1) {
  4. if (!map.containsKey(i)) {
  5. map.put(i, 1);
  6. } else {
  7. map.put(i, map.get(i) + 1);
  8. }
  9. }
  10. List<Integer> list = new ArrayList<>();
  11. for (int i : nums2) {
  12. if (map.containsKey(i) && map.get(i) >= 1) {
  13. list.add(i);
  14. map.put(i, map.get(i) - 1);
  15. } else {
  16. continue;
  17. }
  18. }
  19. int[] ans = new int[list.size()];
  20. int index = 0;
  21. for (int i : list) {
  22. ans[index++] = i;
  23. }
  24. return ans;
  25. }

202. 快乐数

https://leetcode-cn.com/problems/happy-number/
题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!
所以这道题目使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。

  1. public boolean isHappy(int n) {
  2. HashSet<Integer> set = new HashSet<>();
  3. while (n != 1) {
  4. int sum = 0;
  5. while (n != 0) {
  6. sum += Math.pow(n % 10, 2);
  7. n /= 10;
  8. }
  9. n = sum;
  10. if (set.contains(n)) {
  11. break;
  12. }
  13. set.add(n);
  14. }
  15. return n == 1;
  16. }

5. 两数之和

https://leetcode-cn.com/problems/two-sum/

  1. public int[] twoSum(int[] nums, int target) {
  2. Map<Integer, Integer> map = new HashMap<>();
  3. for (int i = 0; i < nums.length; i++) {
  4. if (map.containsKey(target - nums[i])) {
  5. return new int[]{map.get(target - nums[i]), i};
  6. }
  7. map.put(nums[i], i);
  8. }
  9. return new int[]{-1, -1};
  10. }

454. 四数相加Ⅱ

https://leetcode-cn.com/problems/4sum-ii/

  1. public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
  2. HashMap<Integer, Integer> map = new HashMap<>();
  3. int ans = 0;
  4. for (int i = 0; i < nums1.length; i++) {
  5. for (int j = 0; j < nums2.length; j++) {
  6. int sum = nums1[i] + nums2[j];
  7. if (map.containsKey(sum)) {
  8. map.put(sum, map.get(sum) + 1);
  9. } else {
  10. map.put(sum, 1);
  11. }
  12. }
  13. }
  14. for (int i = 0; i < nums3.length; i++) {
  15. for (int j = 0; j < nums4.length; j++) {
  16. int sum = nums3[i] + nums4[j];
  17. if (map.containsKey(-sum) && map.get(-sum) > 0) {
  18. ans += map.get(-sum);
  19. }
  20. }
  21. }
  22. return ans;
  23. }

15. 三数之和

https://leetcode-cn.com/problems/3sum/
排序+ 双指针
哈希表专题 - 图1

  1. public List<List<Integer>> threeSum(int[] nums) {
  2. // 排序
  3. Arrays.sort(nums);
  4. List<List<Integer>> ans = new ArrayList<>();
  5. for (int i = 0; i < nums.length; i++) {
  6. if (i == 0 || nums[i] != nums[i - 1]) { // 去重
  7. List<LinkedList<Integer>> nexts = twoSum(nums, i + 1, -nums[i]);
  8. for (LinkedList<Integer> next : nexts) {
  9. next.addFirst(nums[i]);
  10. ans.add(next);
  11. }
  12. }
  13. }
  14. return ans;
  15. }
  16. // nums是排好序的
  17. private List<LinkedList<Integer>> twoSum(int[] nums, int begin, int target) {
  18. List<LinkedList<Integer>> ans = new ArrayList<>();
  19. int L = begin;
  20. int R = nums.length - 1;
  21. while (L < R) {
  22. if (nums[L] + nums[R] > target) {
  23. R--;
  24. } else if (nums[L] + nums[R] < target) {
  25. L++;
  26. } else {
  27. if (L == begin || nums[L - 1] != nums[L]) { // 去重
  28. LinkedList<Integer> cur = new LinkedList<>();
  29. cur.add(nums[L]);
  30. cur.add(nums[R]);
  31. ans.add(cur);
  32. }
  33. L++;
  34. }
  35. }
  36. return ans;
  37. }

18. 四数之和

https://leetcode-cn.com/problems/4sum/

  1. public List<List<Integer>> fourSum(int[] nums, int target) {
  2. // 排序
  3. Arrays.sort(nums);
  4. List<List<Integer>> ans = new ArrayList<>();
  5. for (int i = 0; i <= nums.length - 4; i++) {
  6. if (i == 0 || nums[i] != nums[i - 1]) { //去重
  7. List<LinkedList<Integer>> nexts = threeSum(nums, i + 1, target - nums[i]);
  8. for (LinkedList<Integer> next : nexts) {
  9. next.addFirst(nums[i]);
  10. ans.add(next);
  11. }
  12. }
  13. }
  14. return ans;
  15. }
  16. private List<LinkedList<Integer>> threeSum(int[] nums, int begin, int target) {
  17. List<LinkedList<Integer>> ans = new ArrayList<>();
  18. for (int i = begin; i <= nums.length - 3; i++) {
  19. if (i == begin || nums[i] != nums[i - 1]) {
  20. List<LinkedList<Integer>> nexts = twoSum(nums, i + 1, target - nums[i]);
  21. for (LinkedList<Integer> next : nexts) {
  22. next.addFirst(nums[i]);
  23. ans.add(next);
  24. }
  25. }
  26. }
  27. return ans;
  28. }
  29. // nums是排好序的
  30. private List<LinkedList<Integer>> twoSum(int[] nums, int begin, int target) {
  31. List<LinkedList<Integer>> ans = new ArrayList<>();
  32. int L = begin;
  33. int R = nums.length - 1;
  34. while (L < R) {
  35. if (nums[L] + nums[R] > target) {
  36. R--;
  37. } else if (nums[L] + nums[R] < target) {
  38. L++;
  39. } else {
  40. if (L == begin || nums[L] != nums[L - 1]) {
  41. LinkedList<Integer> cur = new LinkedList<>();
  42. cur.add(nums[L]);
  43. cur.add(nums[R]);
  44. ans.add(cur);
  45. }
  46. L++;
  47. }
  48. }
  49. return ans;
  50. }