205. 同构字符串

  1. class Solution {
  2. public boolean isIsomorphic(String s, String t) {
  3. Map<Character, Character> map1 = new HashMap<>();
  4. Map<Character, Character> map2 = new HashMap<>();
  5. for (int i = 0, j = 0; i < s.length(); i++, j++) {
  6. if (!map1.containsKey(s.charAt(i))) {
  7. map1.put(s.charAt(i), t.charAt(j)); // map1保存 s[i] 到 t[j]的映射
  8. }
  9. if (!map2.containsKey(t.charAt(j))) {
  10. map2.put(t.charAt(j), s.charAt(i)); // map2保存 t[j] 到 s[i]的映射
  11. }
  12. // 无法映射,返回 false
  13. if (map1.get(s.charAt(i)) != t.charAt(j) || map2.get(t.charAt(j)) != s.charAt(i)) {
  14. return false;
  15. }
  16. }
  17. return true;
  18. }
  19. }

242. 有效的字母异位词

用哈希表记录

  1. class Solution {
  2. public boolean isAnagram(String s, String t) {
  3. if (s.length() != t.length()){
  4. return false;
  5. }
  6. HashMap<Character , Integer> map = new HashMap<>();
  7. for (int i = 0; i < s.length(); i++) {
  8. char c = s.charAt(i);
  9. map.put(c,map.getOrDefault(c,0)+1);
  10. }
  11. for (int i = 0; i < t.length(); i++) {
  12. char c = t.charAt(i);
  13. map.put(c,map.getOrDefault(c,0)-1);
  14. if (map.get(c) < 0){
  15. return false;
  16. }
  17. }
  18. return true;
  19. }
  20. }

用数组去记录

record数组长度记录为26是因为全是小写字母ASCII表里面26个小写字母是连续的我们只需要记录每一个字母在ASCII表里的一个相对位置即可

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

383. 赎金信

使用哈希表记录

  1. class Solution {
  2. public boolean canConstruct(String ransomNote, String magazine) {
  3. HashMap<Character, Integer> map = new HashMap<>();
  4. for (int i = 0; i < magazine.length(); i++) {
  5. char c = magazine.charAt(i);
  6. map.put(c,map.getOrDefault(c,0)+1);
  7. }
  8. for (int i = 0; i < ransomNote.length(); i++) {
  9. char c = ransomNote.charAt(i);
  10. map.put(c,map.getOrDefault(c,0)-1);
  11. if (map.get(c)<0){
  12. return false;
  13. }
  14. }
  15. return true;
  16. }
  17. }

用数组记录

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

49. 字母异位词分组 不会写!记得要看,代码抄的

class Solution { public List> groupAnagrams(String[] strs) { //判断是否为空字符串数组 if(strs == null || strs.length == 0){ return new ArrayList(); } //1.创建一个哈希表 Map map = new HashMap(); for (String s: strs) { //将字符串转化为字符数组 char[] chars = s.toCharArray(); //对字符数组按照字母顺序排序 Arrays.sort(chars); //将排序后的字符串作为哈希表中的key值 String key = String.valueOf(chars); //2.判读哈希表中是否有该key值 if (!map.containsKey(key)){ //若不存在,则为新的异位词语,在map中创建新的键值对 map.put(key,new ArrayList()); } //3.将该字符串放在对应key的list中 map.get(key).add(s); } //返回map中所有键值对象构成的list return new ArrayList(map.values()); } }

349. 两个数组的交集

  1. import java.util.HashSet;
  2. import java.util.Set;
  3. class Solution {
  4. public int[] intersection(int[] nums1, int[] nums2) {
  5. if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0) {
  6. return new int[0];
  7. }
  8. Set<Integer> set1 = new HashSet<>();
  9. Set<Integer> resSet = new HashSet<>();
  10. //遍历数组1
  11. for (int i : nums1) {
  12. set1.add(i);
  13. }
  14. //遍历数组2的过程中判断哈希表中是否存在该元素
  15. for (int i : nums2) {
  16. if (set1.contains(i)) {
  17. resSet.add(i);
  18. }
  19. }
  20. int[] resArr = new int[resSet.size()];
  21. int index = 0;
  22. //将结果几何转为数组
  23. for (int i : resSet) {
  24. resArr[index++] = i;
  25. }
  26. return resArr;
  27. }
  28. }

350. 两个数组的交集 II

因为结果要求可重复的数组,这里就不能用HashSet了我们选用数组

  1. class Solution {
  2. public int[] intersect(int[] nums1, int[] nums2) {
  3. HashMap<Integer, Integer> n1 = new HashMap<>();
  4. for (int i : nums1) {
  5. n1.put(i,n1.getOrDefault(i,0)+1);
  6. }
  7. int[] rs = new int[Math.min(nums1.length,nums2.length)];//选用数组
  8. int index = 0;
  9. for (int i : nums2) {
  10. if (n1.containsKey(i) && n1.getOrDefault(i,0) >0){
  11. rs[index++] = i;
  12. //取出结果
  13. n1.put(i,n1.getOrDefault(i,0)-1);
  14. }
  15. }
  16. return Arrays.copyOfRange(rs, 0, index);//截取目标数组
  17. }
  18. }

202. 快乐数

  1. class Solution {
  2. private int getNextNumber(int n) {
  3. int res = 0;
  4. while (n > 0) {
  5. int temp = n % 10;
  6. res += temp * temp;
  7. n = n / 10;
  8. }
  9. return res;
  10. }
  11. public boolean isHappy(int n){
  12. HashSet<Integer> set = new HashSet<>();
  13. while (n != 1 && !set.contains(n)){
  14. set.add(n);
  15. n = getNextNumber(n);
  16. }
  17. return n == 1;
  18. }
  19. }


1. 两数之和

解析

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

454. 四数相加 II

题目没有要求每个数组只能使用一次

  1. class Solution {
  2. public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
  3. Map<Integer, Integer> map = new HashMap<>();
  4. int temp;
  5. int res = 0;
  6. //统计两个数组中的元素之和,同时统计出现的次数,放入map
  7. for (int i : nums1) {
  8. for (int j : nums2) {
  9. temp = i + j;
  10. if (map.containsKey(temp)) {
  11. map.put(temp, map.get(temp) + 1);
  12. } else {
  13. map.put(temp, 1);
  14. }
  15. }
  16. }
  17. //统计剩余的两个元素的和,在map中找是否存在相加为0的情况,同时记录次数
  18. for (int i : nums3) {
  19. for (int j : nums4) {
  20. temp = i + j;
  21. if (map.containsKey(0 - temp)) {
  22. res += map.get(0 - temp);
  23. }
  24. }
  25. }
  26. return res;
  27. }
  28. }

总结,看到形如:A+B….+N=0的式子,要转换为(A+…T)=-((T+1)…+N)再计算,这个T的分割点一般是一半,特殊情况下需要自行判断。定T是解题的关键。

15. 三数之和

labuladong题解的通用模板
代码随想录

  1. class Solution {
  2. public List<List<Integer>> threeSum(int[] nums) {
  3. List<List<Integer>> result = new ArrayList<>();
  4. Arrays.sort(nums);
  5. for (int i = 0; i < nums.length; i++) {
  6. if (nums[i] > 0) {
  7. return result;
  8. }
  9. if (i > 0 && nums[i] == nums[i - 1]) {
  10. continue;
  11. }
  12. int left = i + 1;
  13. int right = nums.length - 1;
  14. while (right > left) {
  15. int sum = nums[i] + nums[left] + nums[right];
  16. if (sum > 0) {
  17. right--;
  18. } else if (sum < 0) {
  19. left++;
  20. } else {
  21. result.add(Arrays.asList(nums[i], nums[left], nums[right]));
  22. while (right > left && nums[right] == nums[right - 1]) right--;
  23. while (right > left && nums[left] == nums[left + 1]) left++;
  24. right--;
  25. left++;
  26. }
  27. }
  28. }
  29. return result;
  30. }
  31. }

NSum之和时候要是题目没要求返回数组下标而是返回值,都可以用排序 + 双指针

18. 四数之和

  1. class Solution {
  2. public List<List<Integer>> fourSum(int[] nums, int target) {
  3. List<List<Integer>> result = new ArrayList<>();
  4. Arrays.sort(nums);
  5. for (int i = 0; i < nums.length; i++) {
  6. if (i > 0 && nums[i - 1] == nums[i]) {//注意这里的判断条件
  7. continue;
  8. }
  9. for (int j = i + 1; j < nums.length; j++) {
  10. if (j > i + 1 && nums[j - 1] == nums[j]) {
  11. continue;
  12. }
  13. int left = j + 1;
  14. int right = nums.length - 1;
  15. while (right > left) {
  16. int sum = nums[i] + nums[j] + nums[left] + nums[right];
  17. if (sum > target) {
  18. right--;
  19. } else if (sum < target) {
  20. left++;
  21. } else {
  22. result.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
  23. while (right > left && nums[right] == nums[right - 1]) right--;
  24. while (right > left && nums[left] == nums[left + 1]) left++;
  25. left++;
  26. right--;
  27. }
  28. }
  29. }
  30. }
  31. return result;
  32. }
  33. }