你正在经营一座摩天轮,该摩天轮共有 4 个座舱 ,每个座舱 最多可以容纳 4 位游客 。你可以 逆时针 轮转座舱,但每次轮转都需要支付一定的运行成本 runningCost
。摩天轮每次轮转都恰好转动 1 / 4 周。
给你一个长度为 n
的数组 customers
, customers[i]
是在第 i
次轮转(下标从 0 开始)之前到达的新游客的数量。这也意味着你必须在新游客到来前轮转 i
次。每位游客在登上离地面最近的座舱前都会支付登舱成本 boardingCost
,一旦该座舱再次抵达地面,他们就会离开座舱结束游玩。
你可以随时停下摩天轮,即便是 在服务所有游客之前 。如果你决定停止运营摩天轮,为了保证所有游客安全着陆,将免费进行所有后续轮转 。注意,如果有超过 4 位游客在等摩天轮,那么只有 4 位游客可以登上摩天轮,其余的需要等待 下一次轮转 。
返回最大化利润所需执行的 最小轮转次数 。 如果不存在利润为正的方案,则返回 -1
。
提示:
n == customers.length
1 <= n <= 105
0 <= customers[i] <= 50
1 <= boardingCost, runningCost <= 100
【模拟】
int minOperationsMaxProfit(int* customers, int customersSize, int boardingCost, int runningCost){
int current=0;//当前还有多少游客没有登上摩天轮
int count=0;//当前轮转的次数
int maxCount=0;//最大利润,轮转的次数
int maxProfit=0; //最大利润
int tmpProfit=0;//当前轮转的所获利润
for(int i=0;i<customersSize;i++){
//统计当前游客数
current=current+customers[i];
//每个座舱最多可以容纳4位游客
if(current>=4){
tmpProfit=tmpProfit+(boardingCost*4-1*runningCost);
current=current-4;
}else{
//游客数少于4,让他们全部上去
tmpProfit=tmpProfit+(boardingCost*current-1*runningCost);
current=0;
}
//记录目前的轮转
count++;
//更新最大利润和最大利润对应的轮转
if(maxProfit<tmpProfit){
maxProfit=tmpProfit;
maxCount=count;
}
}
//没有新游客到达,但是还有游客没有乘坐摩天轮,结束是直到所有游客都乘坐了摩天轮
//循环的内容和之前一样
while(current!=0){
//每个座舱最多可以容纳4位游客
if(current>=4){
tmpProfit=tmpProfit+(boardingCost*4-1*runningCost);
current=current-4;
}else{
//游客数少于4,让他们全部上去
tmpProfit=tmpProfit+(boardingCost*current-1*runningCost);
current=0;
}
//记录目前的轮转
count++;
//更新最大利润和最大利润对应的轮转
if(maxProfit<tmpProfit){
maxProfit=tmpProfit;
maxCount=count;
}
}
//如果不存在利润为正的方案就返回-1,因为maxCount是从0开始的,而且每次都更新最大
//所有当利润为0时就是不存在利润为正的方案
return maxCount!=0?maxCount:-1;
}
定义 str = [s, n]
表示 str
由 n
个字符串 s
连接构成。
str == ["abc", 3] =="abcabcabc"
。如果可以从 s2
中删除某些字符使其变为 s1
,则称字符串 s1
可以从字符串 s2
获得。
s1 = "abc"
可以从 s2 = "ab**\*dbe***c"
获得,仅需要删除加粗且用斜体标识的字符。现在给你两个字符串 s1
和 s2
和两个整数 n1
和 n2
。由此构造得到两个字符串,其中 str1 = [s1, n1]
、str2 = [s2, n2]
。
请你找出一个最大整数 m
,以满足 str = [str2, m]
可以从 str1
获得。
提示:
1 <= s1.length, s2.length <= 100
s1
和 s2
由小写英文字母组成1 <= n1, n2 <= 106
【循环节】466. 统计重复个数 - 力扣(LeetCode)
int getMaxRepetitions(char * s1, int n1, char * s2, int n2){
if(n1==0) return 0;
int len1=strlen(s1),len2=strlen(s2);
int *s2_id=malloc(sizeof(int)*(len2+1)),*s2_cnt=malloc(sizeof(int)*(len2+1));
int id=0,cnt=0;
//查找循环节
for(int i=0;i<n1;i++){
for(int j=0;j<len1;j++){
if(s1[j]==s2[id]){
cnt = id==len2-1 ? cnt+1 : cnt;
id = id==len2-1 ? 0 : id+1;
}
}
//record
s2_id[i]=id;
s2_cnt[i]=cnt;
//search
for(int j=0;j<i;j++){
if(s2_id[j]==s2_id[i]){
//循环节中的s2的个数乘以循环次数
int core=(s2_cnt[i]-s2_cnt[j])*((n1-j-1)/(i-j));
//将剩余的s1的循环个数加到前面,计算除循环节外的个数
int addition=s2_cnt[j+((n1-1-j)%(i-j))];
return (addition+core)/n2;
}
}
}
return s2_cnt[n1-1]/n2;
}
给你一个链表的头节点 head
。
移除每个右侧有一个更大数值的节点。
返回修改后链表的头节点 head
。
提示:
[1, 105]
内1 <= Node.val <= 105
【递归】
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeNodes(struct ListNode* head) {
if (head==NULL) return NULL;
head->next=removeNodes(head->next);
if(head->next != NULL && head->val < head->next->val){
return head->next;
}
else{
return head;
}
}
给你一个下标从 0 开始、大小为 m x n
的二进制矩阵 matrix
;另给你一个整数 numSelect
,表示你必须从 matrix
中选择的 不同 列的数量。
如果一行中所有的 1
都被你选中的列所覆盖,则认为这一行被 覆盖 了。
形式上,假设 s = {c1, c2, ...., cnumSelect}
是你选择的列的集合。对于矩阵中的某一行 row
,如果满足下述条件,则认为这一行被集合 s
覆盖:
matrix[row][col] == 1
的每个单元格 matrix[row][col]
(0 <= col <= n - 1
),col
均存在于 s
中,或者row
中 不存在 值为 1
的单元格。你需要从矩阵中选出 numSelect
个列,使集合覆盖的行数最大化。
返回一个整数,表示可以由 numSelect
列构成的集合 覆盖 的 最大行数 。
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 12
matrix[i][j]
要么是 0
要么是 1
1 <= numSelect <= n
【二进制枚举】
int maximumRows(int **matrix, int matrixSize, int *matrixColSize, int numSelect) {
int m = matrixSize, n = matrixColSize[0];
int *mask = (int *)malloc(sizeof(int) * m);
for (int i = 0; i < m; i++) {
mask[i] = 0;
for (int j = 0; j < n; j++) {
mask[i] += matrix[i][j] << (n - 1 - j);
}
}
int res = 0, limit = 1 << n;
for (int cur = 1; cur < limit; cur++) {
if (__builtin_popcount(cur) != numSelect) {
continue;
}
int t = 0;
for (int j = 0; j < m; j++) {
if ((mask[j] & cur) == mask[j]) {
t++;
}
}
res = res > t ? res : t;
}
free(mask);
return res;
}
有 n
个人排成一个队列,从左到右 编号为 0
到 n - 1
。给你以一个整数数组 heights
,每个整数 互不相同,heights[i]
表示第 i
个人的高度。
一个人能 看到 他右边另一个人的条件是这两人之间的所有人都比他们两人 矮 。更正式的,第 i
个人能看到第 j
个人的条件是 i < j
且 min(heights[i], heights[j]) > max(heights[i+1], heights[i+2], ..., heights[j-1])
。
请你返回一个长度为 n
的数组 answer
,其中 answer[i]
是第 i
个人在他右侧队列中能 看到 的 人数 。
提示:
n == heights.length
1 <= n <= 105
1 <= heights[i] <= 105
heights
中所有数 互不相同 。【单调栈】
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* canSeePersonsCount(int* heights, int heightsSize, int* returnSize) {
int n = heightsSize;
int stackSize = 0;
int* stack = (int*)malloc(n * sizeof(int));
int* res = (int*)malloc(n * sizeof(int));
*returnSize = n;
for (int i = n - 1; i >= 0; i--) {
int h = heights[i];
res[i] = 0;
while (stackSize > 0 && stack[stackSize - 1] <= h) {
stackSize--;
res[i] += 1;
}
if (stackSize > 0) {
res[i] += 1;
}
stack[stackSize++] = h;
}
free(stack);
return res;
}
给你一个链表的头 head
,每个结点包含一个整数值。
在相邻结点之间,请你插入一个新的结点,结点值为这两个相邻结点值的 最大公约数 。
请你返回插入之后的链表。
两个数的 最大公约数 是可以被两个数字整除的最大正整数。
提示:
[1, 5000]
之间。1 <= Node.val <= 1000
【模拟】
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
int gcd(int a, int b) {
while (b != 0) {
int tmp = a % b;
a = b;
b = tmp;
}
return a;
}
struct ListNode* insertGreatestCommonDivisors(struct ListNode* head) {
struct ListNode * node = head;
while (node->next) {
struct ListNode *newNode = (struct ListNode *)malloc(sizeof(struct ListNode));
newNode->val = gcd(node->val, node->next->val);
newNode->next = node->next;
node->next = newNode;
node = newNode->next;
}
return head;
}
给你两个字符串:ransomNote
和 magazine
,判断 ransomNote
能不能由 magazine
里面的字符构成。
如果可以,返回 true
;否则返回 false
。
magazine
中的每个字符只能在 ransomNote
中使用一次。
提示:
1 <= ransomNote.length, magazine.length <= 105
ransomNote
和 magazine
由小写英文字母组成【hash-count】
bool canConstruct(char* ransomNote, char* magazine) {
if(strlen(ransomNote)>strlen(magazine)){
return false;
}
int cnt[26]={0};
for(int i=0;i<strlen(magazine);i++){
cnt[magazine[i]-'a']++;
}
for(int i=0;i<strlen(ransomNote);i++){
char t=ransomNote[i];
if(cnt[t-'a']<=0){
return 0;
}
cnt[t-'a']--;
}
return 1;
}