当前位置:   article > 正文

华为实习技术面手撕代码_手撕代码是什么意思

手撕代码是什么意思

手撕代码–任务调度器(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);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

手撕代码–航班预定统计(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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/642682
推荐阅读
相关标签
  

闽ICP备14008679号