七月集训----贪心

目录

题目一:2078. 两栋颜色不同且距离最远的房子

解题思路:

题目二:561. 数组拆分 I

解题思路:

题目三:1323. 6 和 9 组成的最大数字

解题思路:

题目四:942. 增减字符串匹配

 解题思路:


题目一:2078. 两栋颜色不同且距离最远的房子

街上有 n 栋房子整齐地排成一列,每栋房子都粉刷上了漂亮的颜色。给你一个下标从 0 开始且长度为 n 的整数数组 colors ,其中 colors[i] 表示第  i 栋房子的颜色。

返回 两栋 颜色 不同 房子之间的 最大 距离。

第 i 栋房子和第 j 栋房子之间的距离是 abs(i - j) ,其中 abs(x) 是 x 的绝对值。

解题思路:

直接遍历每栋房子,若此栋房子之后的房子颜色不同,则计算它们之间的距离,将距离最大的用变量max进行存储。

代码:

int maxDistance(int* colors, int colorsSize){
  int i = 0;
  int k;
  int S;
  int max = 0;
  while(i < colorsSize)  //遍历每栋房子
  {
    k = i+1;
    while(k < colorsSize)  //遍历此栋房子之后的所有房子
    {
      if(colors[k] != colors[i])  //颜色不同则计算距离并且与当前记录的max比较
      {
        S = abs(k - i);
        if(S > max)
          max = S;
      }
      k++;
    }
    i++;
  }
    return max;
}

题目二:561. 数组拆分 I

给定长度为 2n 的整数数组 nums ,你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), ..., (an, bn) ,使得从 1 到 n 的 min(ai, bi) 总和最大。

返回该 最大总和 。

解题思路:

 如果我们采用试数的方式, 若第一对中含有1这个数字,因为1是最小的数,那么与1成对的另一个数则一定会被舍弃。其实这里就有点田忌赛马的感觉,用1和其他数中最小的数字(即2)绑定,接着,用3和其他数中最小的数字(即4)绑定,这样,到所有数成对时,min的总和值就会最大。

所以数就分成min[1,2],   min[3,4],    min[5,6]..........[2n-1,2n]

因此,结果就是排序后,每个数组下标为奇数的值相加。

代码:

int Findpos(int *a, int low, int high)  //快排
{
  int val = a[low];
  while(low < high)
  {
    while(low < high && a[high] >= val)
      high--;
    a[low] = a[high];
    while(low < high && a[low] <= val)
      low++;
    a[high] = a[low];
  }
    a[low] = val;
    return high;
}
void Quicksort(int *a,int low, int high)
    {
      if(low < high)
      {
        int pos = Findpos(a,low,high);
        Quicksort(a,low,pos-1);
        Quicksort(a,pos+1, high);
      }   
    }

int arrayPairSum(int* nums, int numsSize){
    int sum = 0;
    if(numsSize== 0)
      return;
    Quicksort(nums,0,numsSize-1);  

    for(int i=0;i<numsSize; i+=2)  //下标为奇数的值相加
    {
      sum =  sum + nums[i];
    }

    return sum;

}

刚开始排序的时候使用的是冒泡,结果超出时间限制,然后就采用时间复杂度更小的快速排序来排,不过说实话C语言略微有点麻烦,许多功能都得自己实现,不像python,C++等可以直接调用库函数。


题目三:1323. 6 和 9 组成的最大数字

给你一个仅由数字 6 和 9 组成的正整数 num

你最多只能翻转一位数字,将 6 变成 9,或者把 9 变成 6 。

请返回你可以得到的最大数字。

解题思路:

看示例其实就是遍历数字的最高位到最低位,如果是6,则把它变成9,然后输出。

int maximum69Number (int num){
  int shuliang = 0;
  int a[5];
  while(num != 0)  //从个位到最高位进行提取,放到a数组中
  { 
    a[shuliang] = num%10;
    num = num /10;
    shuliang++;
  }
  int i,res = 0;
  for(i=shuliang-1; i>=0; i--)    //最高位到最低位,如果是6,则把它变成9,接着break退出循环
  {
    if(a[i] == 6)
    {
      a[i] = 9;
      break;
    }
  }
  for(i=shuliang-1; i>=0; i--)   //将数组内的数字组合成结果
  {
      res = res * 10 + a[i];
  }
  return res;

}

题目四:942. 增减字符串匹配

由范围 [0,n] 内所有整数组成的 n + 1 个整数的排列序列可以表示为长度为 n 的字符串 s ,其中:

如果 perm[i] < perm[i + 1] ,那么 s[i] == 'I' 
如果 perm[i] > perm[i + 1] ,那么 s[i] == 'D' 
给定一个字符串 s ,重构排列 perm 并返回它。如果有多个有效排列perm,则返回其中 任何一个 。

 解题思路:

刚开始看题目还有点云里雾里,看了一下题解才知道大概的意思,求解的话就是定义两个双指针i与j,其中i = 0,j= strlen(s),进一步的,i其实是代表从[0,strlen(s)]这个范围中能选到的最小值,如i=0,即当前在上述的范围中能选到的最小值为0;

而J是代表从[0,strlen(s)]这个范围中能选到的最大值,如j=strlen(s),即当前在上述的范围中能选到的最大值为strlen(s)。

如果当前位置字符串的值为‘I’,则代表后一元素一定比当前位置大,那么当前位置的值一定是在未选择数中最小的(即为i的值),那么后者无论如何都会比当前位置的值要大;同样的,若为'D',则在未选择数中选最大的(即为j的值)。

而在代码层面:遍历字符串s,如果s[k] =='I'则将i的值赋给新数组exam[k],并且i加一;反之则将j的值赋给exam[k],并且j加1。

代码:

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* diStringMatch(char * s, int* returnSize){
    int i = 0;             //定义i和j的值
    int len = strlen(s);
    int j = len;

    int * exam = (int *)malloc(sizeof(int) * (len+1));  //动态分配数组

    for(int k=0; k<len; k++)   //遍历字符串数组s中的所有元素
    {
      if(s[k] == 'I')
      {
        exam[k] = i;
        i++;
      }
      else if(s[k] == 'D')
      {
        exam[k] = 'D';
        j--;
      }
    }
    exam[len] = i;   //最后i一定会等于j,把i或j放到数组最后一个元素中
    return exam;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值