leecode更新

This commit is contained in:
markilue 2023-04-14 13:20:40 +08:00
parent 6d66747962
commit 90237fe746
3 changed files with 307 additions and 0 deletions

View File

@ -0,0 +1,91 @@
package com.markilue.leecode.hot100;
import java.util.Arrays;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100
*@Author: markilue
*@CreateTime: 2023-04-14 10:05
*@Description:
* TODO 力扣621 任务调度器:
* 给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表
* 其中每个字母表示一种不同种类的任务任务可以以任意顺序执行并且每个任务都可以在 1 个单位时间内执行完在任何一个单位时间CPU 可以完成一个任务或者处于待命状态
* 然而两个 相同种类 的任务之间必须有长度为整数 n 的冷却时间因此至少有连续 n 个单位时间内 CPU 在执行不同的任务或者在待命状态
* 你需要计算完成所有任务所需要的 最短时间
*@Version: 1.0
*/
public class T100_LeastInterval {
/**
* 评论区贪心算法:
* 速度击败83.55% 内存击败20.41% 2ms
* @param tasks
* @param n
* @return
*/
public int leastInterval(char[] tasks, int n) {
int[] count = new int[26];//记录每个单词出现的次数
//遍历task记录次数
for (char task : tasks) {
count[task - 'A']++;
}
//排序count找出最大的count
Arrays.sort(count);
//那么最小的长度就是最大的长度按间隔n来
//因为相同元素必须有n个冷却时间假设A出现3次n = 2任务要执行完至少形成AXX AXX A序列X看作预占位置
int minLength = (n + 1) * (count[25] - 1) + 1;//count-1是因为最后一个不用间隔只需要+1
//挨个遍历,找到相同的count的就+1
//剩余的任务次数有两种情况
//1.与A出现次数相同比如B任务最优插入结果是ABX ABX AB中间还剩两个空位当前序列长度+1
//2.比A出现次数少若还有X则按序插入X位置比如C出现两次形成ABC ABC AB的序列
//直到X预占位置还没插满剩余元素逐个放入X位置就满足冷却时间至少为n
for (int i = 24; i >= 0; i--) {
if (count[i] == count[25]) minLength++;
else break;
}
//最后一种情况:全插满了还有多的
//在任意插满区间这里是ABC后面按序插入剩余元素比如ABCD ABCD发现D之间距离至少为n+1肯定满足冷却条件
//因此当X预占位置能插满时最短序列长度就是task.length不能插满则取最少预占序列长度
return Math.max(minLength, tasks.length);
}
/**
* 官方最快:
* 不用排序:时间复杂度降为O(n)
* 速度击败100% 内存击败23.82% 1ms
* @param tasks
* @param n
* @return
*/
public int leastInterval1(char[] tasks, int n) {
int len = tasks.length;
int[] nums = new int[26];
for (int i = 0; i < len; i++) {
nums[tasks[i] - 'A']++;
}
int max = 0;
for (int i = 0; i < 26; i++) {
max = Math.max(max,nums[i]);
}
int count = 0;
for (int i = 0; i < 26; i++) {
if (nums[i] == max) {
count++;
}
}
int res = (n + 1) * (max - 1) + count;
if (len > res) {
return len;
}
return res;
}
}

View File

@ -0,0 +1,92 @@
package com.markilue.leecode.hot100;
import org.junit.Test;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100
*@Author: markilue
*@CreateTime: 2023-04-14 10:42
*@Description:
* TODO 力扣647 回文子串:
* 给你一个字符串 s 请你统计并返回这个字符串中 回文子串 的数目
* 回文字符串 是正着读和倒过来读一样的字符串
* 子字符串 是字符串中的由连续字符组成的一个序列
* 具有不同开始位置或结束位置的子串即使是由相同的字符组成也会被视作不同的子串
*@Version: 1.0
*
*/
public class T101_CountSubstrings {
@Test
public void test() {
System.out.println(countSubstrings("aaa"));
}
/**
* 思路:
* 动态规划:判断一个子串是不是回文如果是就+1
* dp[i][j]表示以i结尾以j开头的子串是不是回文
* 速度击败21.4% 内存击败41.25% 12ms
* @param s
* @return
*/
public int countSubstrings(String s) {
boolean[][] dp = new boolean[s.length() + 1][s.length() + 1];
int count = 0;
dp[0][0] = true;
for (int i = 1; i < dp.length; i++) {
for (int j = i; j >= 1; j--) {
if (s.charAt(j - 1) == s.charAt(i - 1)) {
if (j >= i - 1) {
dp[i][j] = true;
} else {
dp[i][j] = dp[i - 1][j + 1];
}
}
if (dp[i][j]) count++;
}
}
return count;
}
/**
* 官方双指针法:
* 速度击败99.95% 内存击败58.65% 1ms
* @param s
* @return
*/
public int countSubstrings1(String s) {
int result = 0;
char[] chars = s.toCharArray();
int length = chars.length;
for (int i = 0; i < chars.length; i++) {
result +=extend(chars,i,i,length);//以i为中心
result+=extend(chars,i,i+1,length);//以i和i+1为中心
}
return result;
}
public int extend(char[] chars, int i, int j, int length) {
int count = 0;
while (i >= 0 && j < length && chars[i] == chars[j]) {
count++;
i--;
j++;
}
return count;
}
}

View File

@ -0,0 +1,124 @@
package com.markilue.leecode.hot100;
import org.junit.Test;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.PriorityQueue;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100
*@Author: markilue
*@CreateTime: 2023-04-14 11:06
*@Description:
* TODO 力扣739 每日温度:
* 给定一个整数数组 temperatures 表示每天的温度返回一个数组 answer
* 其中 answer[i] 是指对于第 i 下一个更高温度出现在几天后如果气温在这之后都不会升高请在该位置用 0 来代替
*@Version: 1.0
*/
public class T102_DailyTemperatures {
@Test
public void test() {
int[] temperatures = {73, 74, 75, 71, 69, 72, 76, 73};
System.out.println(Arrays.toString(dailyTemperatures1(temperatures)));
}
/**
* 用一个单调栈记录
* @param temperatures
* @return
*/
public int[] dailyTemperatures(int[] temperatures) {
LinkedList<Integer> stack = new LinkedList<>();
int[] result = new int[temperatures.length];
for (int i = temperatures.length - 1; i >= 0; i--) {
int index = 0;
int size = stack.size();
while (!stack.isEmpty() && temperatures[i] > stack.peek()) {
index++;
stack.poll();
}
result[i] = index == size ? 0 : index;
stack.offer(temperatures[i]);
}
return result;
}
/**
* 使用一个优先队列进行记录对应的位置
* 速度击败43.8% 内存击败86.5% 41ms
* @param temperatures
* @return
*/
public int[] dailyTemperatures1(int[] temperatures) {
PriorityQueue<int[]> queue = new PriorityQueue<>(new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0] == o2[0] ? o1[1] - o2[1] : o1[0] - o2[0];
}
});
int[] result = new int[temperatures.length];
for (int i = temperatures.length - 1; i >= 0; i--) {
while (!queue.isEmpty() && temperatures[i] >= queue.peek()[0]) {
queue.poll();
}
if (queue.isEmpty()) {
result[i] = 0;
} else {
result[i] = queue.peek()[1] - i;
}
queue.offer(new int[]{temperatures[i], i});
}
return result;
}
/**
* 官方最快:充分利用result去寻找一个比他更大的值
* 速度击败100% 内存击败95.63% 7ms
* @param temperatures
* @return
*/
public int[] dailyTemperatures2(int[] temperatures) {
int max = 0;
int[] ans = new int[temperatures.length];
for (int i = ans.length-1; i >= 0; i--) {
int currTemp = temperatures[i];
if (currTemp >= max) {
max = currTemp;
continue;
}
int days = 1;
while (temperatures[i+days] <= currTemp) {
days += ans[i+days];
}
ans[i] = days;
}
return ans;
}
}