From 60f7c9d91fdd57d8f39683aecc424618ce7115da Mon Sep 17 00:00:00 2001 From: zhangsan <646228430@qq.com> Date: Thu, 8 May 2025 11:05:42 +0800 Subject: [PATCH] =?UTF-8?q?5.8=20=E4=BA=8C=E8=BD=AE=20=E5=93=88=E5=B8=8C+?= =?UTF-8?q?=E5=8C=BA=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/hash/CanConstruct.java | 33 ++++++++++ .../java/hash/ContainsNearbyDuplicate.java | 30 +++++++++ src/main/java/hash/IsAnagram.java | 27 ++++++++ src/main/java/hash/IsHappy.java | 48 ++++++++++++++ src/main/java/hash/IsIsomorphic.java | 65 +++++++++++++++++++ src/main/java/hash/WordPattern.java | 39 +++++++++++ src/main/java/range/Insert.java | 49 ++++++++++++++ src/main/java/range/SummaryRanges.java | 60 +++++++++++++++++ src/test/java/hash/IsHappyTest.java | 22 +++++++ src/test/java/hash/IsIsomorphicTest.java | 16 +++++ 10 files changed, 389 insertions(+) create mode 100644 src/main/java/hash/CanConstruct.java create mode 100644 src/main/java/hash/ContainsNearbyDuplicate.java create mode 100644 src/main/java/hash/IsAnagram.java create mode 100644 src/main/java/hash/IsHappy.java create mode 100644 src/main/java/hash/IsIsomorphic.java create mode 100644 src/main/java/hash/WordPattern.java create mode 100644 src/main/java/range/Insert.java create mode 100644 src/main/java/range/SummaryRanges.java create mode 100644 src/test/java/hash/IsHappyTest.java create mode 100644 src/test/java/hash/IsIsomorphicTest.java diff --git a/src/main/java/hash/CanConstruct.java b/src/main/java/hash/CanConstruct.java new file mode 100644 index 0000000..8fd27a3 --- /dev/null +++ b/src/main/java/hash/CanConstruct.java @@ -0,0 +1,33 @@ +package hash; +/** + * 题目: 383. 赎金信 (canConstruct) + * 描述:给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。 + * + * 如果可以,返回 true ;否则返回 false 。 + * + * magazine 中的每个字符只能在 ransomNote 中使用一次。 + * + * 示例 1: + 输入:ransomNote = "a", magazine = "b" + 输出:false + + * 链接:https://leetcode.cn/problems/ransom-note/ + */ +public class CanConstruct { + public boolean canConstruct(String ransomNote, String magazine) { + if (ransomNote.length() > magazine.length()) { + return false; + } + int[] cnt = new int[26]; + for (char c : magazine.toCharArray()) { + cnt[c - 'a']++; + } + for (char c : ransomNote.toCharArray()) { + cnt[c - 'a']--; + if(cnt[c - 'a'] < 0) { + return false; + } + } + return true; + } +} diff --git a/src/main/java/hash/ContainsNearbyDuplicate.java b/src/main/java/hash/ContainsNearbyDuplicate.java new file mode 100644 index 0000000..96531f2 --- /dev/null +++ b/src/main/java/hash/ContainsNearbyDuplicate.java @@ -0,0 +1,30 @@ +package hash; + +import java.util.HashMap; +import java.util.Map; + +/** + * 题目: 219. 存在重复元素 II (containsNearbyDuplicate) + * 描述:给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] == nums[j] 且 abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false 。 + * + * + * 示例 1: + 输入:nums = [1,2,3,1], k = 3 + 输出:true + + * 链接:https://leetcode.cn/problems/contains-duplicate-ii/ + */ +public class ContainsNearbyDuplicate { + public boolean containsNearbyDuplicate(int[] nums, int k) { + Mapmap=new HashMap<>(); + for (int i = 0; i < nums.length; i++) { + if(map.containsKey(nums[i])){ + if(i-map.get(nums[i])<=k) + return true; + else map.put(nums[i],i); + }else + map.put(nums[i],i); + } + return false; + } +} diff --git a/src/main/java/hash/IsAnagram.java b/src/main/java/hash/IsAnagram.java new file mode 100644 index 0000000..e57a4e5 --- /dev/null +++ b/src/main/java/hash/IsAnagram.java @@ -0,0 +1,27 @@ +package hash; +/** + * 题目: 242. 有效的字母异位词 (isAnagram) + * 描述:给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的 字母异位词。 + *字母异位词是通过重新排列不同单词或短语的字母而形成的单词或短语,并使用所有原字母一次。 + * + * 示例 1: + 输入: s = "anagram", t = "nagaram" + 输出: true + + * 链接:https://leetcode.cn/problems/valid-anagram/ + */ +public class IsAnagram { + public boolean isAnagram(String s, String t) { + if(s.length() != t.length()) + return false; + int[] alpha = new int[26]; + for(int i = 0; i< s.length(); i++) { + alpha[s.charAt(i) - 'a'] ++; + alpha[t.charAt(i) - 'a'] --; + } + for(int i=0;i<26;i++) + if(alpha[i] != 0) + return false; + return true; + } +} diff --git a/src/main/java/hash/IsHappy.java b/src/main/java/hash/IsHappy.java new file mode 100644 index 0000000..3488de4 --- /dev/null +++ b/src/main/java/hash/IsHappy.java @@ -0,0 +1,48 @@ +package hash; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +/** + * 题目: 202. 快乐数 (IsHappy) + * 描述:编写一个算法来判断一个数 n 是不是快乐数。 + * + * 「快乐数」 定义为: + * + * 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。 + * 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。 + * 如果这个过程 结果为 1,那么这个数就是快乐数。 + * 如果 n 是 快乐数 就返回 true ;不是,则返回 false 。 + * + * 示例 1: + 输入:n = 19 + 输出:true + 解释: + 12 + 92 = 82 + 82 + 22 = 68 + 62 + 82 = 100 + 12 + 02 + 02 = 1 + + * 链接:https://leetcode.cn/problems/happy-number/ + */ +public class IsHappy { + private int next(int n) { + int sum = 0; + while (n > 0) { + int digit = n % 10; + sum += digit * digit; + n /= 10; + } + return sum; + } + + public boolean isHappy(int n) { + Set seen = new HashSet<>(); + while (n != 1 && !seen.contains(n)) { + seen.add(n); + n = next(n); + } + return n == 1; + } +} diff --git a/src/main/java/hash/IsIsomorphic.java b/src/main/java/hash/IsIsomorphic.java new file mode 100644 index 0000000..dad216e --- /dev/null +++ b/src/main/java/hash/IsIsomorphic.java @@ -0,0 +1,65 @@ +package hash; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * 题目: 205. 同构字符串 (isIsomorphic + * 描述:给定两个字符串 s 和 t ,判断它们是否是同构的。 + * 如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。 + * 每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。 + * + * 示例 1: + 输入:s = "egg", t = "add" + 输出:true + + * 链接:https://leetcode.cn/problems/isomorphic-strings/ + */ +public class IsIsomorphic { + public boolean isIsomorphic(String s, String t) { + int cnt=s.length(); + if(cnt!=t.length()) + return false; + Mapmap1=new HashMap<>(); + Mapmap2=new HashMap<>(); + for (int i = 0; i < cnt; i++) { + char curs=s.charAt(i),curt=t.charAt(i); + if(!map1.containsKey(curs)&&!map2.containsKey(curt)) { + map1.put(curs, curt); + map2.put(curt,curs); + } + else if(!map1.containsKey(curs)&&map2.containsKey(curt)||map1.containsKey(curs)&&!map2.containsKey(curt)) + return false; + else{ + if(!map1.get(curs).equals(curt)) + return false; + } + } + return true; + } + + public boolean isIsomorphic2(String s, String t) { + int n = s.length(); + if (n != t.length()) return false; + + Map map = new HashMap<>(n); + Set used = new HashSet<>(n); + + for (int i = 0; i < n; i++) { + char cs = s.charAt(i), ct = t.charAt(i); + + if (map.containsKey(cs)) { + // 已有映射,检查一致性 + if (map.get(cs) != ct) return false; + } else { + // 新的映射,确保 ct 还没被用过 + if (used.contains(ct)) return false; + map.put(cs, ct); + used.add(ct); + } + } + return true; + } +} diff --git a/src/main/java/hash/WordPattern.java b/src/main/java/hash/WordPattern.java new file mode 100644 index 0000000..ff76397 --- /dev/null +++ b/src/main/java/hash/WordPattern.java @@ -0,0 +1,39 @@ +package hash; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * 题目: 290. 单词规律 (wordPattern) + * 描述:给定一种规律 pattern 和一个字符串 s ,判断 s 是否遵循相同的规律。 + * + * 这里的 遵循 指完全匹配,例如, pattern 里的每个字母和字符串 s 中的每个非空单词之间存在着双向连接的对应规律。 + * + * 示例 1: + 输入: pattern = "abba", s = "dog cat cat dog" + 输出: true + + * 链接:https://leetcode.cn/problems/word-pattern/ + */ +public class WordPattern { + public boolean wordPattern(String pattern, String s) { + String[] res=s.split("\\s"); + if(res.length!=pattern.length()) + return false; + Map map=new HashMap<>(); + Setset=new HashSet<>(); + for (int i = 0; i < pattern.length(); i++) { + char cur=pattern.charAt(i); + if(map.containsKey(cur)) { + if(!map.get(cur).equals(res[i])) return false; + }else{ + if(set.contains(res[i]))return false; + map.put(cur,res[i]); + set.add(res[i]); + } + } + return true; + } +} diff --git a/src/main/java/range/Insert.java b/src/main/java/range/Insert.java new file mode 100644 index 0000000..ce186fa --- /dev/null +++ b/src/main/java/range/Insert.java @@ -0,0 +1,49 @@ +package range; + +import java.util.ArrayList; +import java.util.List; + +/** + * 题目: 57. 插入区间 (insert) + * 描述:给你一个 无重叠的 ,按照区间起始端点排序的区间列表 intervals,其中 intervals[i] = [starti, endi] 表示第 i 个区间的开始和结束,并且 intervals 按照 starti 升序排列。同样给定一个区间 newInterval = [start, end] 表示另一个区间的开始和结束。 + * 在 intervals 中插入区间 newInterval,使得 intervals 依然按照 starti 升序排列,且区间之间不重叠(如果有必要的话,可以合并区间)。 + * 返回插入之后的 intervals。 + * 注意 你不需要原地修改 intervals。你可以创建一个新数组然后返回它。 + * + * 示例 1: + 输入:intervals = [[1,3],[6,9]], newInterval = [2,5] + 输出:[[1,5],[6,9]] + + * 链接:https://leetcode.cn/problems/insert-interval/ + */ +//想起来有点复杂。 +public class Insert { + public int[][] insert(int[][] intervals, int[] newInterval) { + List res = new ArrayList<>(); + int i = 0, n = intervals.length; + + // 第一阶段:添加所有在 newInterval 左侧且不重叠的区间 + while (i < n && intervals[i][1] < newInterval[0]) { + res.add(intervals[i]); + i++; + } + + // 第二阶段:与 newInterval 重叠的区间,合并到 newInterval + while (i < n && intervals[i][0] <= newInterval[1]) { + newInterval[0] = Math.min(newInterval[0], intervals[i][0]); + newInterval[1] = Math.max(newInterval[1], intervals[i][1]); + i++; + } + // 把合并后的 newInterval 加进去 + res.add(newInterval); + + // 第三阶段:添加所有在 newInterval 右侧且不重叠的区间 + while (i < n) { + res.add(intervals[i]); + i++; + } + + // 转回二维数组并返回 + return res.toArray(new int[res.size()][]); + } +} diff --git a/src/main/java/range/SummaryRanges.java b/src/main/java/range/SummaryRanges.java new file mode 100644 index 0000000..ca4fe73 --- /dev/null +++ b/src/main/java/range/SummaryRanges.java @@ -0,0 +1,60 @@ +package range; + +import java.util.ArrayList; +import java.util.List; + +/** + * 题目:228. 汇总区间 (summaryRanges) + * 描述:给定一个 无重复元素 的 有序 整数数组 nums 。 + * + * 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums 的数字 x 。 + * + * 列表中的每个区间范围 [a,b] 应该按如下格式输出: + * + * "a->b" ,如果 a != b + * "a" ,如果 a == b + * + * 链接:https://leetcode.cn/problems/summary-ranges/ + * + 示例 1: + 输入:nums = [0,1,2,4,5,7] + 输出:["0->2","4->5","7"] + 解释:区间范围是: + [0,2] --> "0->2" + [4,5] --> "4->5" + [7,7] --> "7" + + */ +public class SummaryRanges { + public List summaryRanges(int[] nums) { + List ranges = new ArrayList<>(); + if (nums == null || nums.length == 0) { + return ranges; + } + + int start = nums[0], end = nums[0]; + StringBuilder sb = new StringBuilder(); + + for (int i = 1; i < nums.length; i++) { + if (nums[i] == end + 1) { + end = nums[i]; + } else { + sb.append(start); + if (start != end) { + sb.append("->").append(end); + } + ranges.add(sb.toString()); + sb.setLength(0); + start = end = nums[i]; + } + } + + sb.append(start); + if (start != end) { + sb.append("->").append(end); + } + ranges.add(sb.toString()); + + return ranges; + } +} diff --git a/src/test/java/hash/IsHappyTest.java b/src/test/java/hash/IsHappyTest.java new file mode 100644 index 0000000..78554b1 --- /dev/null +++ b/src/test/java/hash/IsHappyTest.java @@ -0,0 +1,22 @@ +package hash; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static org.junit.Assert.*; + +public class IsHappyTest { + + @Test + public void isHappy() { + int n = 19; + IsHappy solution = new IsHappy(); + boolean res=solution.isHappy(n); + if(res) + System.out.println("yes"); + else System.out.println("no"); + } +} \ No newline at end of file diff --git a/src/test/java/hash/IsIsomorphicTest.java b/src/test/java/hash/IsIsomorphicTest.java new file mode 100644 index 0000000..42fd021 --- /dev/null +++ b/src/test/java/hash/IsIsomorphicTest.java @@ -0,0 +1,16 @@ +package hash; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class IsIsomorphicTest { + + @Test + public void isIsomorphic() { + String s = "egg", t = "add"; + IsIsomorphic solution = new IsIsomorphic(); + solution.isIsomorphic(s,t); + + } +} \ No newline at end of file