算法-贪心猫的鱼干大分配 | 豆包MarsCode AI刷题

46 阅读3分钟
  • 题目解析: 问题描述如下:每只猫有一个等级,等级越高的猫应该得到更多的鱼干。1.每只猫至少有一斤;2.猫等级高于它相邻,比相邻的获得更多。求最少准备多少?

开始的时候没啥思路,先写下了测试样例

  1. [1, 2, 2]-->4
  2. [6, 5, 4, 3, 2, 16]-->17
  3. [1, 2, 2, 3, 3, 20, 1, 2, 3, 3, 2, 1, 5, 6, 6, 5, 5, 7, 7, 4]-->35

我发现可以先第一次比较后简单转换成1和0的数组,简化数组,方便进行下一步的数据处理

  1. [0, 1, 0]
  2. [1, 1, 1, 1, 0, 1]
  3. [0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0]

然后讲具有连续三个以上1的字段再判断,比如2[]的[1111]和3[]的[1111]、[111]的字段 进行长度除以2,取商进行递增,如果是奇数那么中间的值是商+1,比如一个字段是[1111111]-->取商为3,中间的值为4-->[1234321]。如果首位是1那么首位为最大值,逐渐递减。因此,还要先进行首位判断。而最终的数量需要每只猫都要加一后相加。总之,我写出了很长的代码。如下:

  •   def solution(n, cats_levels):
      row = []  
      crr = cats_levels  
    
    
      if crr[0] > crr[1]:  
          row.append(1)  
      else:  
          row.append(0)  
    
    
      for i in range(1, n - 1):  
          if crr[i] > crr[i - 1] or crr[i] > crr[i + 1]:  
              row.append(1)  
          else:  
              row.append(0)  
    
    
      if crr[n - 1] > crr[n - 2]:  
          row.append(1)  
      else:  
          row.append(0)  
    
    
      def addc(o):  
          s = 0  
          for i in range(1, o + 1):  
              s += i  
          return s  
    
    
      def O_o(r, w, row2):  
          a = []  
          b = []  
          m = 0  
    
    
          for x in range(r, w):  
              if row2[x] == 0:  
                  a.append(x)  
    
    
          for y in range(1, len(a)):  
              b.append(a[y] - a[y - 1] - 1)  
    
    
          for j in range(len(b)):  
              if b[j] < 3:  
                  m += b[j]  
              else:  
                  bj = b[j] // 2  
                  if b[j] % 2 == 1:  
                      m += addc(bj) * 2 + bj + 1  
                  else:  
                      m += addc(bj) * 2  
    
          return m  
    
      y1 = 0  
      y2 = 0  
      y = 0  
    
      if row[0] == 0 and row[n - 1] == 0:  
          n += O_o(0, len(row), row)  
      elif row[0] == 1 and row[n - 1] == 0:  
          for x in range(len(row)):  
              if row[x] == 1:  
                  y += 1  
              else:  
                  n += O_o(x, len(row), row) + addc(y)  
                  break  
      elif row[0] == 0 and row[n - 1] == 1:  
          for x in range(len(row) - 1, -1, -1):  
              if row[x] == 1:  
                  y += 1  
              else:  
                  n += O_o(0, len(row) - y, row) + addc(y)  
                  break  
      else:
          for x in range(len(row)):  
              if row[x] == 1:  
                  y1 += 1  
              else:  
                  break  
          for x in range(len(row) - 1, -1, -1):  
              if row[x] == 1:  
                  y2 += 1  
              else:  
                  break  
          n += O_o(y1 + 1, n - y1 - y2, row) + addc(y1) + addc(y2)  
    
      return n
           
    

虽然感觉逻辑是对的,但是测试错误,我现在想来发现可以简略一些。因为一定会有一份,因此在总数上加上第一次0和1的数组中的1的数量,如果有连续字段,进行长度判断就好了。第一次写完时纠结了下便没继续想了。

再回看时,豆包进行提醒,重点如下:1.简化逻辑:通过两次遍历数组,分别从前向后和从后向前更新鱼干的分配,确保每只猫的鱼干数满足题目要求。2.边界条件:通过两次遍历,避免了复杂的边界条件处理。 然后便有了如下代码:

def solution(n, cats_levels):
# 初始化鱼干分配列表
fish_distribution = [1] * n

# 根据等级差异分配鱼干
for i in range(1, n):
    if cats_levels[i] > cats_levels[i - 1]:
        fish_distribution[i] = fish_distribution[i - 1] + 1

for i in range(n - 2, -1, -1):
    if cats_levels[i] > cats_levels[i + 1]:
        fish_distribution[i] = max(fish_distribution[i], fish_distribution[i + 1] + 1)

# 计算总鱼干数
total_fish = sum(fish_distribution)
return total_fish

运行通过了......

  • 总结:很明显,我的思路不太一样,但是豆包用了简便和快速的方法,逻辑上也非常的简单粗暴。

  • 学习计划:我可以利用豆包进行快速的刷题,简单的思路后,询问豆包,确认思考方向,提高学习效率。避免陷入执拗,浪费时间。

  • 工具运用:刷题刷得比较少,但是时间宝贵,比较少。但是用豆包后就可以合理利用进行快速刷题。