n
个人站成一排,按从 1
到 n
编号。
最初,排在队首的第一个人拿着一个枕头。每秒钟,拿着枕头的人会将枕头传递给队伍中的下一个人。一旦枕头到达队首或队尾,传递方向就会改变,队伍会继续沿相反方向传递枕头。
n
个人时,TA 会将枕头传递给第 n - 1
个人,然后传递给第 n - 2
个人,依此类推。给你两个正整数 n
和 time
,返回 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;
}
给你一个餐馆信息数组 restaurants
,其中 restaurants[i] = [idi, ratingi, veganFriendlyi, pricei, distancei]
。你必须使用以下三个过滤器来过滤这些餐馆信息。
其中素食者友好过滤器 veganFriendly
的值可以为 true
或者 false
,如果为 true 就意味着你应该只包括 veganFriendlyi
为 true 的餐馆,为 false 则意味着可以包括任何餐馆。此外,我们还有最大价格 maxPrice
和最大距离 maxDistance
两个过滤器,它们分别考虑餐厅的价格因素和距离因素的最大值。
过滤后返回餐馆的 id,按照 *rating* 从高到低排序。如果 *rating* 相同,那么按 *id* 从高到低排序。简单起见, veganFriendlyi
和 veganFriendly
为 true 时取值为 1,为 false 时,取值为 0 。
提示:
1 <= restaurants.length <= 10^4
restaurants[i].length == 5
1 <= idi, ratingi, pricei, distancei <= 10^5
1 <= maxPrice, maxDistance <= 10^5
veganFriendlyi
和 veganFriendly
的值为 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;
}
给你一个下标从 0 开始的二维整数数组 flowers
,其中 flowers[i] = [starti, endi]
表示第 i
朵花的 花期 从 starti
到 endi
(都 包含)。同时给你一个下标从 0 开始大小为 n
的整数数组 people
,people[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;
}
假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
给你一个整数数组 flowerbed
表示花坛,由若干 0
和 1
组成,其中 0
表示没种植花,1
表示种植了花。另有一个数 n
,能否在不打破种植规则的情况下种入 n
朵花?能则返回 true
,不能则返回 false
。
提示:
1 <= flowerbed.length <= 2 * 104
flowerbed[i]
为 0
或 1
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;
}
你有 n
枚花的种子。每枚种子必须先种下,才能开始生长、开花。播种需要时间,种子的生长也是如此。给你两个下标从 0 开始的整数数组 plantTime
和 growTime
,每个数组的长度都是 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;
}
给定一个数组 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;
}
给你一个整数数组 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;
}
【动态规划】
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[i−1][0],dp[i−1][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[i−1][1],dp[i−1][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];
}