华为实习技术面手撕代码

手撕代码–任务调度器(Leecode 621):

给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间,CPU 可以完成一个任务,或者处于待命状态。

然而,两个 相同种类 的任务之间必须有长度为整数 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。

你需要计算完成所有任务所需要的 最短时间 。

力扣(LeetCode)

基本思路:

看完题目,感觉是使用贪心去算。

  1. 首先想到对每个任务统计个数
  2. 然后先安排好最多个数的任务,再将剩余任务插在每一个最多个数任务的后面
  3. 当时只给了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 上预订的座位总数。

力扣(LeetCode)

基本思路:

  1. 暴力求解:很容易想到。遍历二维数组,以每个数组的索引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;
    }
}
  1. 前缀和思想:前缀和即索引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;
}
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值