leecode更新
This commit is contained in:
parent
6d66747962
commit
90237fe746
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue