手撕代码–任务调度器(Leecode 621):
给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间,CPU 可以完成一个任务,或者处于待命状态。
然而,两个 相同种类 的任务之间必须有长度为整数 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。
你需要计算完成所有任务所需要的 最短时间 。
基本思路:
看完题目,感觉是使用贪心去算。
- 首先想到对每个任务统计个数
- 然后先安排好最多个数的任务,再将剩余任务插在每一个最多个数任务的后面
- 当时只给了15分钟手撕,有这样大概思路去写了,出错后发现对题目的很多意思都没读懂
画个图其实思路就会清晰很多:
代码:
import java.util.*;
public class Main1{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String[] temp = sc.next().split(",");
char[] tasks = new char[temp.length];
for(int i=0;i<temp.length;i++){
tasks[i]=temp[i].charAt(0);
}
int n = sc.nextInt();
System.out.println(solution(tasks,n));
}
}
public static int solution(char[] tasks, int n){
//一维数组记录每个大写字母及任务的出现次数
int[] arr = new int[26];
for(char c:tasks){
arr[c-'A']++;
}
//对任务次数数组进行排序
Arrays.sort(arr);
//上图中已说明
int res = (arr[25]-1)*(n+1)+1;
//若出现最大任务书相同的,那么必定会排在最后,这时res需要加1
for(int i=24;i>=0&&arr[i]>0;i--){
if(arr[i]==arr[25]){
res++;
}
}
//若在最大任务数后插入的任务数比冷却时间还多,那么就是返回总的任务数了
//最后需要返回两个之间的最大值才行
return Math.max(res, tasks.length);
}
}
手撕代码–航班预定统计(Leecode 1109):
这里有 n 个航班,它们分别从 1 到 n 进行编号。
有一份航班预订表 bookings ,表中第 i 条预订记录 bookings[i] = [firsti, lasti, seatsi] 意味着在从 firsti 到 lasti (包含 firsti 和 lasti )的 每个航班 上预订了 seatsi 个座位。
请你返回一个长度为 n 的数组 answer,其中 answer[i] 是航班 i 上预订的座位总数。
基本思路:
- 暴力求解:很容易想到。遍历二维数组,以每个数组的索引0和1的元素为边界,遍历加上索引2的预定数。能ac,但是时间复杂度比较高O(N^2).
public static class Solution {
public int[] corpFlightBookings(int[][] bookings, int n) {
int[] res = new int[n];
for(int i=0;i<bookings.length;i++){
for(int j=bookings[i][0]-1;j<=bookings[i][1]-1;j++){
res[j] +=bookings[i][2];
}
}
return res;
}
}
- 前缀和思想:前缀和即索引i位置的值,为i之前所有元素值的和。
所以当第1个+10以后,位置2加10,后面所有的索引值都加10了,但是只有前两个位置值才需要,所以,直接在第三个位置减10,那么第三个位置及之后的索引的值都会减10,相当于10-10=0。
按照这个想法,就是bookings[i][j][0]-1位置加上bookings[i][j][2],在booings[i][j][1]位置减bookings[i][j][2]
代码:
public static int[] solution(int[][] bookings, int n){
int[] res = new int[n];
for(int[] booking:bookings){
res[booking[0]-1]+=booking[2];
if(booking[1]<n){
res[booking[1]]-=booking[2];
}
}
for(int i=1;i<n;i++){
res[i]+=res[i-1];
}
return res;
}