diff --git a/src/main/java/hash/GroupAnagrams.java b/src/main/java/hash/GroupAnagrams.java new file mode 100644 index 0000000..c2fd3ed --- /dev/null +++ b/src/main/java/hash/GroupAnagrams.java @@ -0,0 +1,86 @@ +package hash; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +/** + * 题目:49.字母异位词分组 (groupAnagrams) + * 描述:给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 + * 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 + * 链接:https://leetcode.cn/problems/group-anagrams + * + 示例 1: + 输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"] + 输出: [["bat"],["nat","tan"],["ate","eat","tea"]] + + 示例 2: + 输入: strs = [""] + 输出: [[""]] + + 示例 3: + 输入: strs = ["a"] + 输出: [["a"]] + */ + +//做出来了。 +public class GroupAnagrams { + //计数 + public List> groupAnagrams1(String[] strs) { + // 创建一个 Map,键是编码后的字符串,值是字母异位词列表 + HashMap> map = new HashMap<>(); + + // 遍历输入数组 + for (String str : strs) { + // 统计每个字母出现的次数 + int[] count = new int[26]; + for (char c : str.toCharArray()) { + count[c - 'a']++; // 统计字母出现次数 + } + + // 将字母统计结果编码为字符串 + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 26; i++) { + sb.append('#'); //必须加 [bdddddddddd, bbbbbbbbbbc] 都是01010... 01010... + sb.append(count[i]); + } + String key = sb.toString(); + + // 如果 Map 中不存在该键,则创建一个新的列表 + if (!map.containsKey(key)) { + map.put(key, new ArrayList<>()); + } + + // 将当前单词添加到对应的列表中 + map.get(key).add(str); + } + + // 返回 Map 中的所有值(即字母异位词列表) + return new ArrayList<>(map.values()); + } + //排序 + public List> groupAnagrams(String[] strs) { + // 创建一个 Map,键是标准化后的字符串,值是字母异位词列表 + HashMap> map = new HashMap<>(); + + // 遍历输入数组 + for (String str : strs) { + // 将单词转换为字符数组并排序 + char[] charArray = str.toCharArray(); + Arrays.sort(charArray); + String sortedStr = new String(charArray); + + // 如果 Map 中不存在该键,则创建一个新的列表 + if (!map.containsKey(sortedStr)) { + map.put(sortedStr, new ArrayList<>()); + } + + // 将当前单词添加到对应的列表中 + map.get(sortedStr).add(str); + } + + // 返回 Map 中的所有值(即字母异位词列表) + return new ArrayList<>(map.values()); + } +} diff --git a/src/main/java/hash/LongestConsecutive.java b/src/main/java/hash/LongestConsecutive.java new file mode 100644 index 0000000..16ff926 --- /dev/null +++ b/src/main/java/hash/LongestConsecutive.java @@ -0,0 +1,55 @@ +package hash; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * 题目:128.最长连续序列 (longestConsecutive) + * 描述:给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。 + * 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 + * 链接:https://leetcode.cn/problems/longest-consecutive-sequence/ + * + 示例 1: + 输入:nums = [100,4,200,1,3,2] + 输出:4 + 解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。 + + 示例 2: + 输入:nums = [0,3,7,2,5,8,4,6,0,1] + 输出:9 + + 示例 3: + 输入:nums = [1,0,1,2] + 输出:3 + */ +//没做出来 +public class LongestConsecutive { + public int longestConsecutive(int[] nums) { + // 将数组中的所有元素存入 HashSet + HashSet set = new HashSet<>(); + for (int num : nums) { + set.add(num); + } + int longestStreak = 0; + + // 遍历数组中的每个元素 + for (int num : set) { + // 如果当前元素是连续序列的起点(即没有前驱元素) + if (!set.contains(num - 1)) { + int currentNum = num; + int currentStreak = 1; + + // 计算以当前元素为起点的连续序列的长度 + while (set.contains(currentNum + 1)) { + currentNum++; + currentStreak++; + } + + // 更新最长连续序列的长度 + longestStreak = Math.max(longestStreak, currentStreak); + } + } + + return longestStreak; + } +} diff --git a/src/main/java/hash/TwoSum.java b/src/main/java/hash/TwoSum.java new file mode 100644 index 0000000..f2d8b34 --- /dev/null +++ b/src/main/java/hash/TwoSum.java @@ -0,0 +1,29 @@ +package hash; + +import java.util.HashMap; + +/** + * 题目:1.两数之和 (Two Sum) + * 描述:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回它们的数组下标。 + * 链接:https://leetcode.cn/problems/two-sum/ + * + * 示例 1: + * + * 输入:nums = [2,7,11,15], target = 9 + * 输出:[0,1] + * 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。 + */ +//做出来了。 +public class TwoSum { + public int[] twoSum(int[] nums, int target) { + HashMap map = new HashMap<>(); + for (int i = 0; i < nums.length; i++) { + int complement = target - nums[i]; // 计算补数 + if (map.containsKey(complement)) { + return new int[]{map.get(complement), i}; // 返回补数的索引和当前索引 + } + map.put(nums[i], i); // 将当前元素和索引存入 map + } + throw new IllegalArgumentException("No two sum solution"); // 如果没有解,抛出异常 + } +} \ No newline at end of file diff --git a/src/main/java/slidingwindow/FindAnagrams.java b/src/main/java/slidingwindow/FindAnagrams.java new file mode 100644 index 0000000..c549028 --- /dev/null +++ b/src/main/java/slidingwindow/FindAnagrams.java @@ -0,0 +1,72 @@ +package slidingwindow; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; + +/** + * 题目:438.找到字符串中所有字母异位词 (findAnagrams) + * 描述:给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 + * 链接:https://leetcode.cn/problems/find-all-anagrams-in-a-string/ + * + 示例 1: + 输入: s = "cbaebabacd", p = "abc" + 输出: [0,6] + 解释: + 起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。 + 起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。 + + 示例 2: + 输入: s = "abab", p = "ab" + 输出: [0,1,2] + 解释: + 起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。 + 起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。 + 起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。 + */ + +//没做出来 +public class FindAnagrams { + public List findAnagrams(String s, String p) { + List result = new ArrayList<>(); + if (s == null || p == null || s.length() < p.length()) { + return result; + } + + int[] pCount = new int[26]; + int[] sCount = new int[26]; + + // 统计 p 中每个字符的频率 + for (char c : p.toCharArray()) { + pCount[c - 'a']++; + } + + int windowSize = p.length(); + // 初始化滑动窗口 + for (int i = 0; i < windowSize; i++) { + sCount[s.charAt(i) - 'a']++; + } + + // 比较初始窗口 + if (Arrays.equals(sCount,pCount)) { + result.add(0); + } + + // 滑动窗口 + for (int i = windowSize; i < s.length(); i++) { + // 移除窗口左边的字符 + sCount[s.charAt(i - windowSize) - 'a']--; + // 添加窗口右边的字符 + sCount[s.charAt(i) - 'a']++; + + // 比较当前窗口 + if (Arrays.equals(sCount,pCount)) { + result.add(i - windowSize + 1); + } + } + + return result; + } +} diff --git a/src/main/java/slidingwindow/LengthOfLongestSubstring.java b/src/main/java/slidingwindow/LengthOfLongestSubstring.java new file mode 100644 index 0000000..2bdfd43 --- /dev/null +++ b/src/main/java/slidingwindow/LengthOfLongestSubstring.java @@ -0,0 +1,47 @@ +package slidingwindow; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * 题目:3.无重复字符的最长子串 (lengthOfLongestSubstring) + * 描述:给定一个字符串 s ,请你找出其中不含有重复字符的 最长 子串 的长度。 + * 链接:https://leetcode.cn/problems/longest-substring-without-repeating-characters/ + * + 示例 1: + 输入: s = "abcabcbb" + 输出: 3 + 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 + + 示例 2: + 输入: s = "bbbbb" + 输出: 1 + 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 + 示例 3: + 输入: s = "pwwkew" + 输出: 3 + 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 + 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。 + */ + +public class LengthOfLongestSubstring { + public int lengthOfLongestSubstring(String s) { + int left=0,right=0,max_length=0; + HashSet set=new HashSet<>(); + while (left<=right && rightmax_length){ + max_length=right-left+1; + } + right+=1; + } + else { + set.remove(s.charAt(left)); + left+=1; + } + } + return max_length; + } +} diff --git a/src/main/java/twopointers/MaxArea.java b/src/main/java/twopointers/MaxArea.java new file mode 100644 index 0000000..0f961dd --- /dev/null +++ b/src/main/java/twopointers/MaxArea.java @@ -0,0 +1,58 @@ +package twopointers; +/** + * 题目:11.盛最多水的容器 (maxArea) + * 描述:给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 + * 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 + * 返回容器可以储存的最大水量。 + * 说明:你不能倾斜容器。 + * 链接:https://leetcode.cn/problems/container-with-most-water/ + * + 示例 1: + 输入:[1,8,6,2,5,4,8,3,7] + 输出:49 + 解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。 + + 示例 2: + 输入:height = [1,1] + 输出:1 + */ +public class MaxArea { + + //暴力解法O(N^2) 没过所有例子 + public int maxArea1(int[] height) { + int maxarea=-1; + int temparea=-1; + for (int i = 0; i < height.length; i++) { + for (int j = i+1; j < height.length; j++) { + temparea=(j-i)*Math.min(height[i],height[j]); + if(temparea>maxarea){ + maxarea=temparea; + } + } + } + return maxarea; + } + //双指针 + /** + * 在每个状态下,无论长板或短板向中间收窄一格,都会导致水槽 底边宽度 −1 变短: + * + * 若向内 移动短板 ,水槽的短板 min(h[i],h[j]) 可能变大,因此下个水槽的面积 可能增大 。 + * 若向内 移动长板 ,水槽的短板 min(h[i],h[j]) 不变或变小,因此下个水槽的面积 一定变小 。 + * 因此,初始化双指针分列水槽左右两端,循环每轮将短板向内移动一格,并更新面积最大值,直到两指针相遇时跳出;即可获得最大面积。 + */ + public int maxArea(int[] height) { + int i=0,j=height.length-1; + int maxarea=Integer.MIN_VALUE,temparea=Integer.MIN_VALUE; + while(imaxarea){ + maxarea=temparea; + } + if (height[i]> threeSum(int[] nums) { + List> ans=new ArrayList<>(); + Arrays.sort(nums); + for(int i=0;i0)break; + if(i>0 && nums[i]==nums[i-1])continue; + int j=i+1; + int k=nums.length-1; + int sum=nums[i]+nums[j]+nums[k]; + while(j0)k--; + else { + List temp=new ArrayList<>(); + temp.add(nums[i]); + temp.add(nums[j]); + temp.add(nums[k]); + ans.add(temp); + while(j> result=solution.groupAnagrams1(strs); + for (List list : result) { + System.out.println(list); + } + } + @Test + public void testLongestConsecutive() { + LongestConsecutive solution = new LongestConsecutive(); + // 测试用例 1 + int[] nums1 = {100, 4, 200, 1, 3, 2}; + assertEquals(4, solution.longestConsecutive(nums1)); // 预期输出 4 + } +} diff --git a/src/test/java/slidingwindow/slidingwindowAlgorithmsTest.java b/src/test/java/slidingwindow/slidingwindowAlgorithmsTest.java new file mode 100644 index 0000000..6b2466a --- /dev/null +++ b/src/test/java/slidingwindow/slidingwindowAlgorithmsTest.java @@ -0,0 +1,22 @@ +package slidingwindow; + +import org.junit.Test; + +import java.util.List; + +public class slidingwindowAlgorithmsTest { + @Test + public void testLengthOfLongestSubstring(){ + String s = "pwwkew"; + LengthOfLongestSubstring solution = new LengthOfLongestSubstring(); + int res=solution.lengthOfLongestSubstring(s); + System.out.println(res); + } + @Test + public void testFindAnagrams(){ + String s = "cbaebabacd", p = "abc"; + FindAnagrams solution = new FindAnagrams(); + Listres=solution.findAnagrams(s,p); + System.out.println(res); + } +} diff --git a/src/test/java/twopointers/TwoPointsAlgorithmsTest.java b/src/test/java/twopointers/TwoPointsAlgorithmsTest.java new file mode 100644 index 0000000..b550dc7 --- /dev/null +++ b/src/test/java/twopointers/TwoPointsAlgorithmsTest.java @@ -0,0 +1,31 @@ +package twopointers; + +import org.junit.Test; + +import java.util.List; + +public class TwoPointsAlgorithmsTest { + @Test + public void tesrMoveZeroes(){ + MoveZeroes solution = new MoveZeroes(); + int[] num ={0,1,0,3,12}; + solution.moveZeroes(num); + for (int i : num) { + System.out.println(i); + } + } + @Test + public void testMaxArea(){ + MaxArea solution = new MaxArea(); + int [] height={1,8,6,2,5,4,8,3,7}; + int res=solution.maxArea(height); + System.out.println(res); + } + @Test + public void testThreeSum(){ + ThreeSum solution = new ThreeSum(); + int [] nums={-1,0,1,2,-1,-4}; + List> res = solution.threeSum(nums); + System.out.println(res); + } +}