代码随想录算法训练营第51期第29天 | 134. 加油站、135. 分发糖果、860.柠檬水找零、406.根据身高重建队列

134. 加油站

134. 加油站icon-default.png?t=O83Ahttps://leetcode.cn/problems/gas-station/1.一开始用的是暴力法,就for循环里面套while,超时了,用了随想录上面的C++,也超时了;

2.直接看的贪心的解法,最后不需要取模来得出索引

int canCompleteCircuit(int* gas, int gasSize, int* cost, int costSize) {
    int totalGas = 0;
    int curGas = 0;
    int res = 0;
    for(int i = 0; i < gasSize; i++) {
        totalGas += gas[i] - cost[i]; //总汽油量
        curGas += gas[i] - cost[i]; //当前汽油量
        // 如果当前汽油量变为负数,则更新起始加油站为下一个加油站
        if (curGas < 0) {
            res = i + 1;
            curGas = 0;
        }
    }
    if (totalGas < 0){
        return -1;
    }
    return res;
}

135. 分发糖果

135. 分发糖果icon-default.png?t=O83Ahttps://leetcode.cn/problems/candy/1.这道题要遍历两次我知道,但是具体执行细节有点问题

2.先右边比左边,右边分大就加1

3.再左边比右边,这里还有一个条件,就是左边的糖果小于等于右边

4.这里可以用[1,2,87,87,87,2,1]进行测试

int candy(int* ratings, int ratingsSize) {
    int *can = (int *)malloc(sizeof(int) * ratingsSize);
    int res = 0;
    for(int i = 0; i < ratingsSize; i++) {
        can[i] = 1;
    }
    for (int i = 1; i < ratingsSize; i++) {
        if (ratings[i] > ratings[i-1]) {
            can[i] = can[i-1] + 1;
        }
    }
    for (int i = ratingsSize - 2; i >= 0; i--) {
        if (ratings[i] > ratings[i+1] && can[i] <= can[i+1]) {
            can[i] = can[i+1] + 1;
        }
    }
    for(int i = 0; i < ratingsSize; i++) {
        res += can[i];
    }
    
    return res;
}

860.柠檬水找零

860. 柠檬水找零icon-default.png?t=O83Ahttps://leetcode.cn/problems/lemonade-change/1.这道题倒是很简单,如果不是卡哥放在这里,我可能意识不到这个是贪心

2.一开始用的是malloc申请了内存为2的数组,后来发现直接用静态数组也可以,再后来为了代码含义更清晰,换了两个变量

bool lemonadeChange(int* bills, int billsSize) {
    int fiveDollars = 0;
    int tenDollars = 0;
    for (int i = 0; i < billsSize; i++) {
        if (bills[i] == 5) {
            fiveDollars++;
        } else if (bills[i] == 10) {
            if (fiveDollars > 0) {
                fiveDollars--;
                tenDollars++;
            } else {
                return false;
            }
        } else {
            if (tenDollars > 0 && fiveDollars > 0) {
                tenDollars--;
                fiveDollars--;
            } else if(fiveDollars >= 3) {
                fiveDollars -= 3;
            } else {
                return false;
            }
        }
    }
    return true;
}

406.根据身高重建队列

406. 根据身高重建队列icon-default.png?t=O83Ahttps://leetcode.cn/problems/queue-reconstruction-by-height/1.这个我知道怎么做,但是排序忘了。。

2.这个和分糖果很像,先按高度降序排序,如果高度相同,则按k值升序排序

3.然后按照排序后的k值插入,即可,有一个很有意思的点,就是你在对后面的数值操作的时候,不会对前面的排序造成影响,这个是本题的关键所在

4.这个需要掌握C语言多条件的排序方法

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int cmp(const void *p1, const void *p2) {
    int *pp1 = *(int**)p1;
    int *pp2 = *(int**)p2;
    // 先按高度降序排序,如果高度相同,则按k值升序排序
    return pp1[0] == pp2[0] ? pp1[1] - pp2[1] : pp2[0] - pp1[0];
}
void moveBack(int **people, int peopleSize, int start, int end) {
    int i;
    for (i = end; i > start; i--) {
        people[i] = people[i-1];
    }
}
int** reconstructQueue(int** people, int peopleSize, int* peopleColSize, int* returnSize, int** returnColumnSizes) {
    qsort(people, peopleSize, sizeof(int*), cmp);
    for(int i = 0; i < peopleSize; ++i) {
        int position = people[i][1];
        int *tmp = people[i];
        moveBack(people, peopleSize, position, i);
        people[position] = tmp;
    }
    *returnSize = peopleSize;
    *returnColumnSizes = (int *)malloc(sizeof(int)* peopleSize);
    for(int i = 0; i < peopleSize; i++) {
        (*returnColumnSizes)[i] = 2;
    }
    return people;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值