【Leetcode Sheet】Weekly Practice 6

Leetcode Test

2605 从两个数字数组里生成最小数字(9.5)

给你两个只包含 1 到 9 之间数字的数组 nums1nums2 ,每个数组中的元素 互不相同 ,请你返回 最小 的数字,两个数组都 至少 包含这个数字的某个数位。

提示:

  • 1 <= nums1.length, nums2.length <= 9
  • 1 <= nums1[i], nums2[i] <= 9
  • 每个数组中,元素 互不相同

【hash table】

int minNumber(int* nums1, int nums1Size, int* nums2, int nums2Size){
    int n1=nums1Size,n2=nums2Size;
    int hash[10]={0};
    int min1=10,min2=10;
    for(int i=0;i<n1;i++){
        hash[nums1[i]]++;
        min1=fmin(min1,nums1[i]);
    }
    for(int i=0;i<n2;i++){
        hash[nums2[i]]++;
        min2=fmin(min2,nums2[i]);
    }
    //找出现过2次的数字,以及两个arr中的最小数
    
    int equal=0,min=10;
    for(int i=1;i<10;i++){
        if(hash[i]==2){
            equal=1;
            min=fmin(min,i);
        }
    }
    //有出现过2次数字,直接返回最小数
    
    if(equal) return min;
    
    else{
        if(min1>min2){
            return min1+min2*10;
        }
        else{
            return min2+min1*10;
        }
    }
}

1123 最深叶节点的最近公共祖先(9.6)

给你一个有根节点 root 的二叉树,返回它 最深的叶节点的最近公共祖先

回想一下:

  • 叶节点 是二叉树中没有子节点的节点
  • 树的根节点的 深度0,如果某一节点的深度为 d,那它的子节点的深度就是 d+1
  • 如果我们假定 A 是一组节点 S最近公共祖先S 中的每个节点都在以 A 为根节点的子树中,且 A 的深度达到此条件下可能的最大值。

提示:

  • 树中的节点数将在 [1, 1000] 的范围内。
  • 0 <= Node.val <= 1000
  • 每个节点的值都是 独一无二 的。

【递归】

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

int getDepth(struct TreeNode *root){
    if(!root) return 0;
    //如果root==null,则返回0层
    return fmax(getDepth(root->left),getDepth(root->right))+1;
    //递归返回左右子树,层数++
}

struct TreeNode* lcaDeepestLeaves(struct TreeNode* root){
    struct TreeNode *res=root,*cur=root;
    
    while(cur){  //当cur不为空时
        int left=getDepth(cur->left);
        int right=getDepth(cur->right);
        //left为当前节点的左节点的层
        //right为当前节点的右节点的层
        //层:从叶子节点往上的层数
        
        if(left==right){
            //如果左节点的层==右节点的层,则左右为叶子
            res=cur;
            break;
        }
        else if(left>right){
            //左更深
            cur=cur->left;
        }
        else{
            //右更深
            cur=cur->right;
        }
    }
    return res;
}

2594 修车的最少时间(9.7)

给你一个整数数组 ranks ,表示一些机械工的 能力值ranksi 是第 i 位机械工的能力值。能力值为 r 的机械工可以在 r * n2 分钟内修好 n 辆车。

同时给你一个整数 cars ,表示总共需要修理的汽车数目。

请你返回修理所有汽车 最少 需要多少时间。

**注意:**所有机械工可以同时修理汽车。

提示:

  • 1 <= ranks.length <= 105
  • 1 <= ranks[i] <= 100
  • 1 <= cars <= 106

【二分法】

能力值为r的工人,最多可以修sqrt(t/r)个车

二分上界为:min(ranks) x cars x cars

即让能力最低的人修好所有车,消耗的时间

int check(long long n,int cars,int *ranks,int ranksSize){
    long long sum=0;
    for(int i=0;i<ranksSize;i++){
        sum+=sqrt(n/ranks[i]);
    }
    return sum>=cars;
}

long long repairCars(int *ranks,int ranksSize,int cars){
    long long left=1,right=ranks[0];
    for(int i=0;i<ranksSize;i++){
        right=fmin(ranks[i],right);
    }
    right=right*cars*cars-1;

    while(left<=right){
        long long mid=(left+right)/2;
        if(check(mid,cars,ranks,ranksSize)){
            right=mid-1;
        }
        else{
            left=mid+1;
        }
    }
    return left;
}

2651 计算列车到站时间(9.8)

给你一个正整数 arrivalTime 表示列车正点到站的时间(单位:小时),另给你一个正整数 delayedTime 表示列车延误的小时数。

返回列车实际到站的时间。

注意,该问题中的时间采用 24 小时制。

提示:

  • 1 <= arrivaltime < 24
  • 1 <= delayedTime <= 24

【模拟】

int findDelayedArrivalTime(int arrivalTime, int delayedTime){
    return (arrivalTime+delayedTime)%24;
}

207 课程表(9.9)

你这个学期必须选修 numCourses 门课程,记为 0numCourses - 1

在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai必须 先学习课程 bi

  • 例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1

请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false

提示:

  • 1 <= numCourses <= 2000
  • 0 <= prerequisites.length <= 5000
  • prerequisites[i].length == 2
  • 0 <= ai, bi < numCourses
  • prerequisites[i] 中的所有课程对 互不相同

【拓扑】

题解:207. 课程表 - 力扣(LeetCode)

bool canFinish(int numCourses, int** prerequisites, int prerequisitesSize, int* prerequisitesColSize){
    if(prerequisitesSize==0) return 1;
    int *ans=malloc(sizeof(int)*numCourses);
    for(int i=0;i<numCourses;i++){
        ans[i]=0;
    }
    int res=0;
    for(int i=0;i<prerequisitesSize;i++){
        //update in-point of every point
        ans[prerequisites[i][0]]++;
    }
    for(int i=0;i<numCourses;i++){
        if(ans[i]==0){
            //current course is done
            res++;
            if(res==numCourses){
                //learned courses == total courses
                return 1;
            }
            for(int j=0;j<prerequisitesSize;j++){
                if(prerequisites[j][1]==i){
                    //must-learn course of [j] is learnt
                    ans[prerequisites[j][0]]--;
                }
            }
            ans[i]--;
            i=-1;
        }
    }
    return 0;
}

210 课程表Ⅱ(9.10)

现在你总共有 numCourses 门课需要选,记为 0numCourses - 1。给你一个数组 prerequisites ,其中 prerequisites[i] = [ai, bi] ,表示在选修课程 ai必须 先选修 bi

  • 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示:[0,1]

返回你为了学完所有课程所安排的学习顺序。可能会有多个正确的顺序,你只要返回 任意一种 就可以了。如果不可能完成所有课程,返回 一个空数组

提示:

  • 1 <= numCourses <= 2000
  • 0 <= prerequisites.length <= numCourses * (numCourses - 1)
  • prerequisites[i].length == 2
  • 0 <= ai, bi < numCourses
  • ai != bi
  • 所有[ai, bi] 互不相同

【拓扑】

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* findOrder(int numCourses, int** prerequisites, int prerequisitesSize, int* prerequisitesColSize, int* returnSize){
    int** edges = (int**)malloc(sizeof(int*) * numCourses);
    for (int i = 0; i < numCourses; i++) {
        edges[i] = (int*)malloc(0);
    }
    int edgeColSize[numCourses];
    memset(edgeColSize, 0, sizeof(edgeColSize));
    int indeg[numCourses];
    memset(indeg, 0, sizeof(indeg));
    for (int i = 0; i < prerequisitesSize; ++i) {
        int a = prerequisites[i][1], b = prerequisites[i][0];
        edgeColSize[a]++;
        edges[a] = (int*)realloc(edges[a], sizeof(int) * edgeColSize[a]);
        edges[a][edgeColSize[a] - 1] = b;
        ++indeg[b];
    }

    int q[numCourses];
    int l = 0, r = -1;
    for (int i = 0; i < numCourses; ++i) {
        if (indeg[i] == 0) {
            q[++r] = i;
        }
    }

    int* result = (int*)malloc(sizeof(int) * numCourses);
    int resultSize = 0;

    int visited = 0;
    while (l <= r) {
        ++visited;
        int u = q[l++];
        result[resultSize++] = u;
        for (int i = 0; i < edgeColSize[u]; ++i) {
            --indeg[edges[u][i]];
            if (indeg[edges[u][i]] == 0) {
                q[++r] = edges[u][i];
            }
        }
    }
    for (int i = 0; i < numCourses; i++) {
        free(edges[i]);
    }
    free(edges);
    if (visited == numCourses) {
        *returnSize = numCourses;
    } else {
        *returnSize = 0;
    }
    return result;
}

630 课程表Ⅲ(9.11)

这里有 n 门不同的在线课程,按从 1n 编号。给你一个数组 courses ,其中 courses[i] = [durationi, lastDayi] 表示第 i 门课将会 持续durationi 天课,并且必须在不晚于 lastDayi 的时候完成。

你的学期从第 1 天开始。且不能同时修读两门及两门以上的课程。

返回你最多可以修读的课程数目。

提示:

  • 1 <= courses.length <= 104
  • 1 <= durationi, lastDayi <= 104

【C++的优先队列】(不会orz)

class Solution {
public:
    int scheduleCourse(vector<vector<int>>& courses) {
        sort(courses.begin(), courses.end(), [](const auto& c0, const auto& c1) {
            return c0[1] < c1[1];
        });

        priority_queue<int> q;
        // 优先队列中所有课程的总时间
        int total = 0;

        for (const auto& course: courses) {
            int ti = course[0], di = course[1];
            if (total + ti <= di) {
                total += ti;
                q.push(ti);
            }
            else if (!q.empty() && q.top() > ti) {
                total -= q.top() - ti;
                q.pop();
                q.push(ti);
            }
        }

        return q.size();
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MorleyOlsen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值