64,075
社区成员
今天要学习的内容是贪心思想,贪心思想就是每次都是选取局部最优解,最后就可能得到全局最优解。
思路1:排序之后选最大和最小的两组数据之差
int cmp(const void* str1,const void* str2)
{
return *(int*)str1-*(int*)str2;
}
int maxProductDifference(int* nums, int numsSize){
qsort(nums,numsSize,sizeof(int),cmp);
return (nums[numsSize-1]*nums[numsSize-2])-(nums[0]*nums[1]);
}
思路1:先排序数组,然后从大到小开始枚举,看最后三条边是不是满足两条小边相加>大边,如果不满足,则i--,减小最大边,继续判断,如果遍历完了数组都没有,那么数组元素都不构成三角形返回0即可。
int cmp(const void* str1,const void* str2)
{
return *(int*)str1 - *(int*)str2;
}
int largestPerimeter(int* nums, int numsSize){
qsort(nums,numsSize,sizeof(int),cmp);
for(int i =numsSize-1;i>=2;i--)
{
if(nums[i]<nums[i-1]+nums[i-2])
{
return nums[i]+nums[i-1]+nums[i-2];
}
}
return 0;
}
思路:排序后,将相邻数进行分组,因为相邻两个数取最小值,可以保证砍掉的数字是相比较其他元素更小的,让最大的和次最大的成组,可以保证留下次最大的数字。
int cmp(const void* str1,const void* str2)
{
return *(int*)str1 - *(int*)str2;
}
int arrayPairSum(int* nums, int numsSize){
qsort(nums,numsSize,sizeof(int),cmp);
int sum = 0;
for(int i =0;i<numsSize;i+=2)
{
sum+=nums[i];
}
return sum;
}
思路:排序数组,从后向前,如果最后一个人的体重达到了limit就让他自己坐船走,如果小于limit就要判断,这个局部最重的和局部最轻的加在一起有没有超过limit,如果超过了,就让最重的走,如果没超过,就一起走。
int cmp(const void* str1,const void* str2)
{
return *(int*)str1-*(int*)str2;
}
int numRescueBoats(int* people, int peopleSize, int limit){
qsort(people,peopleSize,sizeof(int),cmp);
int left = 0;
int right = peopleSize-1;
int count = 0;
while(left<=right)
{
if(people[right]==limit)
{
right--;
count++;
}
else
{
if(people[left]+people[right]<=limit)
{
left++;
right--;
count++;
}
else
{
right--;
count++;
}
}
}
return count;
}
思路:将数组拷贝一份然后排序,对原来数组的奇偶位进行插入,观察可以发现,偶数位插入最大值,所以定义一个指针从后向前遍历,排序好的数组,将最大值依次递减插入,
然后将插入完偶数位剩下的数组从后向前插入,这样可以保证,最大值对应小的那一半数字的最大值,完成贪心思想。
int cmp(const void* str1,const void* str2)
{
return *(int*)str1-*(int*)str2;
}
void wiggleSort(int* nums, int numsSize){
int arr[numsSize];
memcpy(arr,nums,sizeof(int)*numsSize);
qsort(arr,numsSize,sizeof(int),cmp);
int arrsize = numsSize-1;
for(int j =1;j<numsSize;j+=2)
{
nums[j] = arr[arrsize];
arrsize--;
}
for(int i =0;i<numsSize;i+=2)
{
nums[i] = arr[arrsize];
arrsize--;
}
}
思路:将饼干和小孩都排序,先拿最小的饼干给最容易饱的小孩,如果饱了,计数器++,不饱就换一块更大的。直到饼干没了或者小孩子都饱了,循环结束
int cmp(const void* str1,const void* str2)
{
return *(int*)str1-*(int*)str2;
}
int findContentChildren(int* g, int gSize, int* s, int sSize){
qsort(g,gSize,sizeof(int),cmp);
qsort(s,sSize,sizeof(int),cmp);
int cookie = 0;
int ans = 0;
int i = 0;
while(cookie<sSize&&i<gSize)
{
if(g[i]>s[cookie])//没吃饱
{
cookie++;
}
else//吃饱了
{
i++;
cookie++;
ans++;
}
}
return ans;
}
思路是:遍历每个数组元素,如果数组元素前一个大于该元素,就把数组元素递增至nums[i-1]+1;然后计数器增加nums[i-1]+1-nums[i]即可(也就是记录从nums[i]到nums[i]+1要加多少个1即可)
int minOperations(int* nums, int numsSize){
if(numsSize==1)
return 0;
int cnt = 0;
int i = 1;
while(i<numsSize)
{
if(nums[i]<=nums[i-1])
{
cnt+=nums[i-1]-nums[i]+1;
nums[i]=nums[i-1]+1;
}
else
{
i++;
}
}
return cnt;
}
思路:先排序数组,然后判断数组的每个元素和前一个元素相比是不是比前一个大,如果不是就递增到nums[i]+1;记录递增次数,最后返回即可。
int cmp(const void* str1,const void* str2)
{
return *(int*)str1-*(int*)str2;
}
int minIncrementForUnique(int* nums, int numsSize){
qsort(nums,numsSize,sizeof(int),cmp);
int ans = 0;
int i = 1;
while(i<numsSize)
{
if(nums[i]<=nums[i-1])
{
ans+=nums[i-1]-nums[i]+1;
nums[i] = nums[i-1]+1;
i++;
}
else
i++;
}
return ans;
}
思路是:先排序,然后枚举第一条和第二条第三条边,判断如果第三条边>前两边之和,就结束第三层循环,用计数器记录第二条和第三条之间,有效的有几条,加到计数器上。然后将第二条进行++。继续枚举第三条。如果第二条和第三条重合了就自增第三条。
int cmp(const void* str1,const void* str2)
{
return *(int*)str1-*(int*)str2;
}
int triangleNumber(int* nums, int numsSize){
qsort(nums,numsSize,sizeof(int),cmp);
int one = 0;
int two = 0;
int three = 0;
int count = 0;
for(one = 0;one<numsSize;one++)
{
two = one+1;
three = two +1;
while(two<numsSize)
{
while(three<numsSize)
{
if(nums[one]+nums[two]<=nums[three])
{
break;
}
three++;
}
count+=three-two-1;
two++;
if(two==three)
three++;
}
}
return count;
}