leecode更新
This commit is contained in:
parent
b5dc4022bc
commit
6eafee1860
|
|
@ -0,0 +1,128 @@
|
|||
package com.markilue.leecode.hot100;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.swing.event.ListDataEvent;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.hot100
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-03-07 10:17
|
||||
*@Description:
|
||||
* TODO 力扣49题 字母异位词分组:
|
||||
* 给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
|
||||
* 字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T26_GroupAnagrams {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String[] str={"eat", "tea", "tan", "ate", "nat", "bat"};
|
||||
// String[] str = {""};
|
||||
// String[] str = {"ac","c"};
|
||||
System.out.println(groupAnagrams(str));
|
||||
}
|
||||
|
||||
List<List<String>> result = new ArrayList<>();
|
||||
List<String> cur = new ArrayList<>();
|
||||
Map<Character, Integer> map = new HashMap<>();
|
||||
Map<Integer,Map<Character, Integer>> bigMap=new HashMap<>();
|
||||
|
||||
//TODO 超出时间限制,第111个无法通过;修改后使用bigmap只在空的时候记录,通过 :速度击败5% 内存击败5%
|
||||
public List<List<String>> groupAnagrams(String[] strs) {
|
||||
boolean[] used = new boolean[strs.length];//记录这个单词是否被使用过
|
||||
for (int i = 0; i < strs.length; i++) {
|
||||
if (!used[i]) {
|
||||
used[i] = true;
|
||||
addMap(strs[i],map,i);
|
||||
cur.add(strs[i]);
|
||||
for (int j = i + 1; j < strs.length; j++) {
|
||||
if (!used[j] && isAnagrams(strs[j],j)) {
|
||||
cur.add(strs[j]);
|
||||
used[j] = true;
|
||||
}
|
||||
}
|
||||
result.add(new ArrayList<>(cur));
|
||||
cur.clear();
|
||||
map.clear();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
public void addMap(String str,Map<Character,Integer> map,int index) {
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
char key = str.charAt(i);
|
||||
map.put(key, map.getOrDefault(key, 0) + 1);
|
||||
}
|
||||
bigMap.put(index, map);
|
||||
}
|
||||
|
||||
public boolean isAnagrams(String curStr,int index) {
|
||||
Map<Character, Integer> curMap = bigMap.getOrDefault(index, new HashMap<>());
|
||||
|
||||
if(curMap.isEmpty()){
|
||||
addMap(curStr,curMap,index);
|
||||
}
|
||||
|
||||
return curMap.equals(map);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 官方计数法:由于互为字母异位词的两个字符串包含的字母相同,
|
||||
* 因此两个字符串中的相同字母出现的次数一定是相同的
|
||||
* 故可以将每个字母出现的次数使用字符串表示,作为哈希表的键。
|
||||
* 速度击败26.63% 内存击败22.41% 10ms
|
||||
* @param strs
|
||||
* @return
|
||||
*/
|
||||
public List<List<String>> groupAnagrams1(String[] strs) {
|
||||
Map<String, List<String>> map = new HashMap<String, List<String>>();
|
||||
for (String str : strs) {
|
||||
int[] counts = new int[26];
|
||||
int length = str.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
counts[str.charAt(i) - 'a']++;
|
||||
}
|
||||
// 将每个出现次数大于 0 的字母和出现次数按顺序拼接成字符串,作为哈希表的键
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < 26; i++) {
|
||||
if (counts[i] != 0) {
|
||||
sb.append((char) ('a' + i));
|
||||
sb.append(counts[i]);
|
||||
}
|
||||
}
|
||||
String key = sb.toString();
|
||||
List<String> list = map.getOrDefault(key, new ArrayList<String>());
|
||||
list.add(str);
|
||||
map.put(key, list);
|
||||
}
|
||||
return new ArrayList<List<String>>(map.values());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 官方合理且最快:通过排序建立key
|
||||
* 速度击败80.36% 内存击败57.98% 6ms
|
||||
* @param strs
|
||||
* @return
|
||||
*/
|
||||
public List<List<String>> groupAnagrams2(String[] strs) {
|
||||
Map<String, List<String>> map = new HashMap<>();
|
||||
for (String str : strs) {
|
||||
char[] cs = str.toCharArray();
|
||||
Arrays.sort(cs);
|
||||
String key = String.valueOf(cs);
|
||||
List<String> list = map.getOrDefault(key, new ArrayList<>());
|
||||
list.add(str);
|
||||
map.put(key, list);
|
||||
}
|
||||
return new ArrayList(map.values());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package com.markilue.leecode.hot100;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.hot100
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-03-07 11:38
|
||||
*@Description:
|
||||
* TODO 力扣53题 最大子数组和:
|
||||
* 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
|
||||
* 子数组 是数组中的一个连续部分。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T27_MaxSubArray {
|
||||
|
||||
@Test
|
||||
public void test(){
|
||||
int[] nums={-2,-1};
|
||||
System.out.println(maxSubArray1(nums));
|
||||
}
|
||||
|
||||
/**
|
||||
* 贪心:要尽可能多的数字,如果等于0了直接抛弃
|
||||
* 速度击败100% 内存击败79.27%
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public int maxSubArray(int[] nums) {
|
||||
int cur = 0;
|
||||
int maxValue = Integer.MIN_VALUE;
|
||||
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
cur += nums[i];
|
||||
if (maxValue < cur) maxValue = cur;
|
||||
if (cur < 0) cur = 0;
|
||||
}
|
||||
return maxValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 动态规划: dp定义为使用nums[0-i]的最大子数组和
|
||||
* 速度击败2.9% 内存击败5.9% 15ms
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public int maxSubArray1(int[] nums) {
|
||||
// if(nums.length==0)return nums[0];
|
||||
int[][] dp = new int[nums.length][2];
|
||||
dp[0][0] = Integer.MIN_VALUE;//至少要一个
|
||||
dp[0][1] = nums[0];//至少要一个
|
||||
|
||||
for (int i = 1; i < nums.length; i++) {
|
||||
|
||||
dp[i][0] = Math.max(dp[i - 1][0], dp[i-1][1]);//现在就不要,全不要
|
||||
dp[i][1] = Math.max(dp[i - 1][1] + nums[i], nums[i]);//要之前,还是不要之前
|
||||
}
|
||||
|
||||
return Math.max(dp[dp.length-1][0],dp[dp.length-1][1]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 动态规划: 滚动数组优化
|
||||
* 速度击败100% 内存击败68.67% 1ms
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public int maxSubArray2(int[] nums) {
|
||||
// if(nums.length==0)return nums[0];
|
||||
|
||||
int dp0 = Integer.MIN_VALUE;//至少要一个
|
||||
int dp1 = nums[0];//至少要一个
|
||||
|
||||
for (int i = 1; i < nums.length; i++) {
|
||||
|
||||
dp0 = Math.max(dp0, dp1);//现在就不要,全不要
|
||||
dp1 = Math.max(dp1 + nums[i], nums[i]);//要之前,还是不要之前
|
||||
}
|
||||
|
||||
return Math.max(dp0,dp1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package com.markilue.leecode.hot100;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.hot100
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-03-07 13:14
|
||||
*@Description:
|
||||
* TODO 力扣55题 跳跃游戏:
|
||||
* 给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。
|
||||
* 数组中的每个元素代表你在该位置可以跳跃的最大长度。
|
||||
* 判断你是否能够到达最后一个下标。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T28_CanJump {
|
||||
|
||||
/**
|
||||
* 思路:贪心,记录一个能到的最大索引
|
||||
* 速度击败94.51% 内存击败97.5% 2ms
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public boolean canJump(int[] nums) {
|
||||
|
||||
if(nums.length==1)return true;
|
||||
|
||||
int maxIndex = 0;
|
||||
int curIndex = 0;
|
||||
|
||||
for (int i = 0; i < nums.length - 1 && i <= maxIndex; i++) {
|
||||
curIndex = i + nums[i];
|
||||
if (curIndex > maxIndex) maxIndex = curIndex;
|
||||
if (maxIndex >= nums.length - 1) return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
package com.markilue.leecode.hot100;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.hot100
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-03-07 13:24
|
||||
*@Description:
|
||||
* TODO 力扣56题 合并区间:
|
||||
* 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。
|
||||
* 请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T29_Merge {
|
||||
|
||||
|
||||
/**
|
||||
* 根据start排序,如果end<start则有重叠区间 7ms
|
||||
* @param intervals
|
||||
* @return
|
||||
*/
|
||||
public int[][] merge(int[][] intervals) {
|
||||
|
||||
Arrays.sort(intervals, (a, b) -> a[0] != b[0] ? a[0] - b[0] : a[1] - b[1]);
|
||||
List<int[]> list = new ArrayList<>();
|
||||
|
||||
for (int[] interval : intervals) {
|
||||
if (list.isEmpty() || list.get(list.size() - 1)[1] < interval[0]) {
|
||||
list.add(interval);
|
||||
} else {
|
||||
int length = list.size() - 1;
|
||||
int[] last = list.get(length);
|
||||
last[1] = Math.max(last[1], interval[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return list.toArray(new int[0][0]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 官方较快解法:6ms
|
||||
* @param intervals
|
||||
* @return
|
||||
*/
|
||||
public int[][] merge1(int[][] intervals) {
|
||||
//按xstart排序
|
||||
Arrays.sort(intervals, new Comparator<int[]>() {
|
||||
@Override
|
||||
public int compare(int[] o1, int[] o2) {
|
||||
//优化 但是需要警惕超过int范围
|
||||
return o1[0] - o2[0];
|
||||
}
|
||||
});
|
||||
|
||||
//寻找重叠区间,并进行合并
|
||||
int length=0;//记录新数组的长度
|
||||
int[][] result =new int[intervals.length][2];
|
||||
result[0]=intervals[0];
|
||||
int lastEnd=intervals[0][1];
|
||||
|
||||
for (int i = 1; i < intervals.length; i++) {
|
||||
if(lastEnd>=intervals[i][0]){
|
||||
//重叠区间,需要合并
|
||||
lastEnd=Math.max(lastEnd,intervals[i][1]);
|
||||
result[length][1]=lastEnd;
|
||||
}else {
|
||||
//非重叠区间,直接添加
|
||||
length++;
|
||||
result[length]=intervals[i];
|
||||
lastEnd=intervals[i][1];
|
||||
}
|
||||
}
|
||||
//缩短至result的真实长度
|
||||
return Arrays.copyOf(result,length+1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package com.markilue.leecode.hot100;
|
||||
|
||||
/**
|
||||
*@BelongsProject: Leecode
|
||||
*@BelongsPackage: com.markilue.leecode.hot100
|
||||
*@Author: markilue
|
||||
*@CreateTime: 2023-03-07 13:40
|
||||
*@Description:
|
||||
* TODO 力扣62题 不同路径:
|
||||
* 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
|
||||
* 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
|
||||
* 问总共有多少条不同的路径?
|
||||
*@Version: 1.0
|
||||
*/
|
||||
public class T30_UniquePaths {
|
||||
|
||||
/**
|
||||
* 思路:动态规划法 ->当前的位置可以是上面往下走一步,也可以是左边往右边走一步
|
||||
* 速度击败100% 内存击败16.37% 0ms
|
||||
* @param m
|
||||
* @param n
|
||||
* @return
|
||||
*/
|
||||
public int uniquePaths(int m, int n) {
|
||||
|
||||
int[][] dp = new int[m][n];
|
||||
|
||||
for (int i = 0; i < m; i++) {
|
||||
dp[i][0] = 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
dp[0][i] = 1;
|
||||
}
|
||||
|
||||
for (int i = 1; i < m; i++) {
|
||||
for (int j = 1; j < n; j++) {
|
||||
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
|
||||
}
|
||||
}
|
||||
|
||||
return dp[m - 1][n - 1];
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue