leedcode_贪心算法系列

时间:2021-03-09 16:51:12

861. 翻转矩阵后的得分

思路:

行首的权值最大,故首先将其置1;

每列由于权值相同,故只需要将0多于1的情况反转即可

763. 划分字母区间

思路:

1.计算每个字母的最右边界下标,并记录到新数组中

2.通过遍历原数组,当下标与当前的最右边界相等时,即表示当前字母可以覆盖前面所有字母的最右边界;

划分出新区间,同时当前的下标更新为新区间的左边界

122. 买卖股票的最佳时机 II

思路:

每当后面的数比前一个数大,就将其差价加到利润中

765. 情侣牵手

思路:

确定对应的情侣数(0对1,2对3,,,),查找并将其替换

860. 柠檬水找零

思路:

  判断是否为5,10,20;是则按数量找零,零钱不够时返回false

 bool lemonadeChange(int* bills, int billsSize) {
int i,j,k;
int use[+] = {,,,,};
for (i = ; i < billsSize ; i ++)
{
switch(bills[i])
{
case :
use[]++;break;
case :
use[]++;
if (use[]>)
use[]--;
else
return false;
break;
case :
use[]++;
if (use[]>)
{ if (use[]>)
{
use[]--,use[]--;
}
else if (use[]>)
{
use[] -= ;
}
else
return false;
}
else
return false;
break;
default:return false;
}
} return true;
}

455. 分发饼干

思路:

  先对饼干大小及小孩胃口做降序排列,然后将两者做比较,使用饼干尽可能满足多的小孩

 int findContentChildren(int* g, int gSize, int* s, int sSize) {
int i,j,k,res = ; //对孩子胃口及饼干大小做降序排列
for (i = ; i < gSize ; i ++)
{
k = i;
for (j=i+; j < gSize ; j ++)
{
if (g[j] > g[k])
k = j;
}
if (i != k)
{
g[i] = g[i] ^ g[k];
g[k] = g[i] ^ g[k];
g[i] = g[i] ^ g[k];
}
}
for (i = ; i < sSize ; i ++)
{
k = i;
for (j=i+; j < sSize ; j ++)
{
if (s[j] > s[k])
k = j;
}
if (i != k)
{
s[i] = s[i] ^ s[k];
s[k] = s[i] ^ s[k];
s[i] = s[i] ^ s[k];
}
} //饼干尽可能得满足小孩
for (i=j=; i<gSize && j<sSize ; )
{
if (s[j]>=g[i])
{
i++,j++;
res ++;
}
else
i++;
} return res;
}

621. 任务调度器

思路:

题意要求不同的任务(字母)间必须有n长度的冷却时间,

1.当n=0时:最短时间即为任务的总长度

2.当n>0时

我们先找出数量最多的任务,即可确定大致的最短时间(n+1)*(max-1)

  然后查找是否还有任务的个数是与max相同,个数初始i=1

  最后得到总长度:(n+1)*(max-1)+i

 #define MAX(X,Y) X>Y?X:Y
int leastInterval(char* tasks, int tasksSize, int n) {
int i,j,k;
int arr[];
memset(arr,,sizeof(arr)); //计算各任务的个数
for (i = ; i < tasksSize ; i ++)
arr[tasks[i]-'A'] ++; //降序处理
for (i = ; i < ; i ++)
{
k = i;
for (j = i+ ; j < ; j ++)
if (arr[j] > arr[k])
k = j;
if (k!=i)
{
arr[i] = arr[i] ^ arr[k];
arr[k] = arr[i] ^ arr[k];
arr[i] = arr[i] ^ arr[k];
}
} //计算最短时间
for (i=; i< ; i ++)
if (arr[i] != arr[])
break; return MAX((arr[]-)*(n+)+i,tasksSize);
}

134. 加油站

思路:

先处理数据得到一组加油耗油后的数据

 1.若处理后的数据总和为负数,车必然不能运行,返回-1

2.分别以非负数为起点,遍历一圈看其能否回到原点

 int canCompleteCircuit(int* gas, int gasSize, int* cost, int costSize) {
int i,j,k,res = -;
int use[gasSize];
memset(use,,sizeof(use)); k = ;
//处理得到加油耗油后的数据
for (i = ; i < gasSize ; i ++)
{
use[i] = gas[i]-cost[i];
k += use[i];
} //剩余油量不能为负数
if (k>=)
{
for (i = ; i < gasSize ; i ++)
{
//以非负数为起点
if (use[i]>=)
{
k = use[i];
//遍历一圈看其能否回到原点
for (j=(i+)%gasSize ; j!=i && k> ; j=(j+)%gasSize)
k += use[j];
if (k>= && j==i)
return i;
}
}
} return res;
}

优化代码:

 int canCompleteCircuit(int* gas, int gasSize, int* cost, int costSize) {
int i,totol,sum,start;
totol = sum = start = ;
for (i = ; i < gasSize ; i ++)
{
totol += gas[i]-cost[i];
sum += gas[i]-cost[i];
if (sum<)
{
sum = ;
start = i+;
}
} return totol<?-:start;
}