• 【Leetcode Sheet】Weekly Practice 9


    Leetcode Test

    2582 递枕头(9.26)

    n 个人站成一排,按从 1n 编号。

    最初,排在队首的第一个人拿着一个枕头。每秒钟,拿着枕头的人会将枕头传递给队伍中的下一个人。一旦枕头到达队首或队尾,传递方向就会改变,队伍会继续沿相反方向传递枕头。

    • 例如,当枕头到达第 n 个人时,TA 会将枕头传递给第 n - 1 个人,然后传递给第 n - 2 个人,依此类推。

    给你两个正整数 ntime ,返回 time 秒后拿着枕头的人的编号。

    提示:

    • 2 <= n <= 1000
    • 1 <= time <= 1000

    【模拟】走到头的时候clk反转

    int passThePillow(int n, int time){
        int cnt=0,pos=1,clk=0;
        while(1){
            if(cnt==time){
                break;
            }
            if(clk==0){
                pos++;
                if(pos==n){
                    clk=1;
                }
            }
            else{
                pos--;
                if(pos==1){
                    clk=0;
                }
            }
            cnt++;
        }
        return pos;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    1333 餐厅过滤器(9.27)

    给你一个餐馆信息数组 restaurants,其中 restaurants[i] = [idi, ratingi, veganFriendlyi, pricei, distancei]。你必须使用以下三个过滤器来过滤这些餐馆信息。

    其中素食者友好过滤器 veganFriendly 的值可以为 true 或者 false,如果为 true 就意味着你应该只包括 veganFriendlyi 为 true 的餐馆,为 false 则意味着可以包括任何餐馆。此外,我们还有最大价格 maxPrice 和最大距离 maxDistance 两个过滤器,它们分别考虑餐厅的价格因素和距离因素的最大值

    过滤后返回餐馆的 id,按照 *rating* 从高到低排序。如果 *rating* 相同,那么按 *id* 从高到低排序。简单起见, veganFriendlyiveganFriendlytrue 时取值为 1,为 false 时,取值为 0 。

    提示:

    • 1 <= restaurants.length <= 10^4
    • restaurants[i].length == 5
    • 1 <= idi, ratingi, pricei, distancei <= 10^5
    • 1 <= maxPrice, maxDistance <= 10^5
    • veganFriendlyiveganFriendly 的值为 0 或 1 。
    • 所有 idi 各不相同。

    【模拟 + 排序】

    /**
     * Note: The returned array must be malloced, assume caller calls free().
     */
    
    int cmp(void *a,void *b){
        int *r1=*(int**)a,*r2=*(int**)b;
        return r1[1]!=r2[1] ? r2[1]-r1[1] : r2[0]-r1[0];
    }
    
    int* filterRestaurants(int** restaurants, int restaurantsSize, int* restaurantsColSize, int veganFriendly, int maxPrice, int maxDistance, int* returnSize){
        int **potential=malloc(sizeof(int*)*restaurantsSize);
        int cnt=0;
        for(int i=0;i<restaurantsSize;i++){
            if(maxPrice<restaurants[i][3]){
                continue;
            }
            else if(maxDistance<restaurants[i][4]){
                continue;
            }
            else if(veganFriendly==1 && restaurants[i][2]==0){
                continue;
            }
            else{
                potential[cnt++]=restaurants[i];
            }
        }
    
        qsort(potential,cnt,sizeof(int*),cmp);
        int *ret=malloc(sizeof(int)*cnt);
        for(int i=0;i<cnt;i++){
            ret[i]=potential[i][0];
        }
    
        *returnSize=cnt;
        return ret;
    }
    
    • 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

    2251 花期内花的数目(9.28)

    给你一个下标从 0 开始的二维整数数组 flowers ,其中 flowers[i] = [starti, endi] 表示第 i 朵花的 花期startiendi (都 包含)。同时给你一个下标从 0 开始大小为 n 的整数数组 peoplepeople[i] 是第 i 个人来看花的时间。

    请你返回一个大小为 n 的整数数组 answer ,其中 answer[i]是第 i 个人到达时在花期内花的 数目

    提示:

    • 1 <= flowers.length <= 5 * 104
    • flowers[i].length == 2
    • 1 <= starti <= endi <= 109
    • 1 <= people.length <= 5 * 104
    • 1 <= people[i] <= 109

    【二分 + 排序】

    /**
     * Note: The returned array must be malloced, assume caller calls free().
     */
    
    int cmp(void* a,void* b){
        return *(int*)a-*(int*)b;
    }
    
    int binarysearch(int *arr,int left,int right,int target){
        while(left<=right){
            int mid=left+(right-left)/2;
            if(arr[mid]>=target){
                right=mid-1;
            }
            else{
                left=mid+1;
            }
        }
        return right;
    }
    
    int* fullBloomFlowers(int** flowers, int flowersSize, int* flowersColSize, int* people, int peopleSize, int* returnSize){
        int n=flowersSize,m=peopleSize;
        int *start=(int*)malloc(sizeof(int)*n),*end=(int*)malloc(sizeof(int)*n);
        for(int i=0;i<n;i++){
            start[i]=flowers[i][0];
            end[i]=flowers[i][1];
        }
    
        qsort(start,n,sizeof(int),cmp);
        qsort(end,n,sizeof(int),cmp);
    
        int *ret=(int*)malloc(sizeof(int)*m);
        *returnSize=m;
        for(int i=0;i<m;i++){
            //search for start & end
            int on=binarysearch(start,0,n-1,people[i]+1);
            int off=binarysearch(end,0,n-1,people[i]);
            ret[i]=on-off;
        }
        return ret;
    }
    
    • 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
    • 38
    • 39
    • 40
    • 41
    • 42

    605 种花问题(9.29)

    假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。

    给你一个整数数组 flowerbed 表示花坛,由若干 01 组成,其中 0 表示没种植花,1 表示种植了花。另有一个数 n ,能否在不打破种植规则的情况下种入 n 朵花?能则返回 true ,不能则返回 false

    提示:

    • 1 <= flowerbed.length <= 2 * 104
    • flowerbed[i]01
    • flowerbed 中不存在相邻的两朵花
    • 0 <= n <= flowerbed.length

    【贪心】遇到可以种的地方就种下

    bool canPlaceFlowers(int* flowerbed, int flowerbedSize, int n){
        for(int i=0;i<flowerbedSize;i++){
            if( (i==0 || flowerbed[i-1]==0) && flowerbed[i]==0 && (i==flowerbedSize-1 || flowerbed[i+1]==0) ){
                n--;
                i++;//the next position cannot plant flower
            }
        }
        return n<=0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2136 全部开花的最早一天(9.30)

    你有 n 枚花的种子。每枚种子必须先种下,才能开始生长、开花。播种需要时间,种子的生长也是如此。给你两个下标从 0 开始的整数数组 plantTimegrowTime ,每个数组的长度都是 n

    • plantTime[i]播种i 枚种子所需的 完整天数 。每天,你只能为播种某一枚种子而劳作。无须 连续几天都在种同一枚种子,但是种子播种必须在你工作的天数达到 plantTime[i] 之后才算完成。
    • growTime[i] 是第 i 枚种子完全种下后生长所需的 完整天数 。在它生长的最后一天 之后 ,将会开花并且永远 绽放

    从第 0 开始,你可以按 任意 顺序播种种子。

    返回所有种子都开花的 最早 一天是第几天。

    提示:

    • n == plantTime.length == growTime.length
    • 1 <= n <= 105
    • 1 <= plantTime[i], growTime[i] <= 104

    【贪心 + 排序】2136. 全部开花的最早一天 - 力扣(LeetCode)

    typedef struct {
        int plant;
        int flower;
    } Grass;
    
    //按照flower(grow)从大到小排序
    int Compare(void *a, void *b)
    {
        Grass *aa = (Grass *)a;
        Grass *bb = (Grass *)b;
        return bb->flower - aa->flower; 
    }
    
    int earliestFullBloom(int* plantTime, int plantTimeSize, int* growTime, int growTimeSize){
        //定义grass-data
        Grass *data = (Grass *)calloc(plantTimeSize, sizeof(Grass));
        for (int i = 0; i < plantTimeSize; i++) {
            data[i].plant = plantTime[i];
            data[i].flower = growTime[i];
        }
    
        qsort(data, plantTimeSize, sizeof(Grass), Compare);
    
        int ans = 0;
        int time = 0;
        for (int i = 0; i < plantTimeSize; i++) {
            //累计种植时间 + 当前植物种植时间 + 当前植物开花时间,最大值更新
            ans = fmax(ans, time + data[i].plant + data[i].flower);
            //增加上一个植物消耗的种植时间,即累计种植时间
            time += data[i].plant;
        }
        return ans;
    }
    
    • 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

    121 买卖股票的最佳时机(10.1)

    给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

    你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

    返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0

    提示:

    • 1 <= prices.length <= 105
    • 0 <= prices[i] <= 104

    【枚举】时间复杂度O(n)

    min 维护的是 prices[i]左侧元素的最小值

    int maxProfit(int* prices, int pricesSize){
        int n=pricesSize,max=0,min=prices[0];
        for(int i=0;i<n;i++){
            max=fmax(max,prices[i]-min);
            //更新最大利益
            min=fmin(min,prices[i]);
            //更新最小值
        }
        return max;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    122 买卖股票的最佳时机Ⅱ(10.2)

    给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。

    在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。

    返回 你能获得的 最大 利润

    提示:

    • 1 <= prices.length <= 3 * 104
    • 0 <= prices[i] <= 104

    【贪心】递增小区间的总和计算

    int maxProfit(int* prices, int pricesSize){
        int ret=0;
        for(int i=1;i<pricesSize;i++){
            ret+=fmax(0,prices[i]-prices[i-1]);
        }
        return ret;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    【动态规划】
    d p [ i ] [ 0 ] 表示第 i 天交易完后手里没有股票的最大利润 dp[i][0]表示第i天交易完后手里没有股票的最大利润 dp[i][0]表示第i天交易完后手里没有股票的最大利润

    d p [ i ] [ 1 ] 表示第 i 天交易完后手里持有一支股票的最大利润 dp[i][1]表示第i天交易完后手里持有一支股票的最大利润 dp[i][1]表示第i天交易完后手里持有一支股票的最大利润

    d p [ i ] [ 0 ] = m a x ( d p [ i − 1 ] [ 0 ] , d p [ i − 1 ] [ 1 ] + p r i c e s [ i ] ) dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]) dp[i][0]=max(dp[i1][0],dp[i1][1]+prices[i])

    d p [ i ] [ 1 ] = m a x ( d p [ i − 1 ] [ 1 ] , d p [ i − 1 ] [ 0 ] − p r i c e s [ i ] ) dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]) dp[i][1]=max(dp[i1][1],dp[i1][0]prices[i])

    没有股票的迭代:前一天没有股票的利润,或,前一天有股票且今天卖出

    有股票的迭代:前一天有股票的利润,或,前一天没有股票且今天买入

    int maxProfit(int* prices, int pricesSize) {
        int dp[pricesSize][2];
        dp[0][0] = 0, dp[0][1] = -prices[0];
        for (int i = 1; i < pricesSize; ++i) {
            dp[i][0] = fmax(dp[i - 1][0], dp[i - 1][1] + prices[i]);
            dp[i][1] = fmax(dp[i - 1][1], dp[i - 1][0] - prices[i]);
        }
        return dp[pricesSize - 1][0];
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    多张图解,一扫你对多线程问题本质的所有误区
    mysql索引条件下推 、 count(*)、count(1)、IN 、exists等
    PG::Photography
    前端UNIAPP端webview嵌入H5使用说明文档
    深度学习入门(五十七)循环神经网络——循环神经网络从零开始实现
    CUDA编程- __syncthreads()函数
    JupyterHub
    RobotFramework框架+Selenium实现UI自动化测试(十六)
    面试机器学习你一定会遇到的知识点汇总
    SQL 主从数据库实时备份
  • 原文地址:https://blog.csdn.net/m0_65787507/article/details/133490111