Python每日一算法之”最接近k个数”(列表函数运用)

问题描述:

给定一个目标数target,一个非负整数k,一个按照升序排列的数组A。在A中找出与target最接近的k个整数,返回这k个数并按照与target的接近程度从小到大排序,如果接近程度相同,那么值小的排在前面。

问题示例:

如果A=[1,2,3],target=2,k=3,那么返回[2,1,3];

如果A=[1,4,6,8],target=3,k=3,那么返回[4,1,6];

代码实现:

其实就是考场对于python列表的操作,以及在python中列表函数应用。

方法1:利用内置列表操作函数(有时候掌握内置列表操作函数是很重要的)

class Solution:
   def Find_k_closest_num(self,L,cloest,target,k):
      op_list = [x-target for x in L]   #得到与target的差值的列表
      abs_list = [abs(x) for x in op_list]  #取绝对值,获取与target的接近值
      for i in range(k):
         min_num = min(abs_list)    #寻找最接近的
         min_index = abs_list.index(min_num)  #得到最接近的值的索引
         cloest.append(op_list[min_index]+target)  #更新cloest列表
         #分别移除abs_list和op_list中已经添加至cloest的元素
         abs_list.remove(min_num)  
         op_list.pop(min_index)

if __name__ == '__main__':
   mylist = []
   cloest = []
   num = int(input("请输入升序排序列表中元素的个数:"))
   for i in range(num):
      data = int(input("请输入元素:"))
      mylist.append(data)
   target = int(input("请输入目标值:"))
   k = int(input("请输入k值:"))
   temp = Solution()
   temp.Find_k_closest_num(mylist,cloest,target,k)
   print(cloest)

输出:

请输入升序排序列表中元素的个数:3
请输入元素:1
请输入元素:2
请输入元素:3
请输入目标值:2
请输入k值:3
[2, 1, 3]


请输入升序排序列表中元素的个数:4
请输入元素:1
请输入元素:4
请输入元素:6
请输入元素:8
请输入目标值:3
请输入k值:3
[4, 1, 6]

方法2:非内置函数解决

class Solution:
   def kClosestNumbers(self,A,target,k):
      #找到a[left]<target,a[right]>=taeget
      #最接近target的两个数,肯定是相邻的
      right = self.find_upper_closest(A,target)
      left = right - 1
      #两指针从中间向两边扩展,依次找到最接近的k个值
      results = []
      for i in range(k):
         if self.is_left_closer(A,target,left,right):
            results.append(A[left])
            left  -= 1
         else:
            results.append(A[right])
            right +=1
      return results

   def find_upper_closest(self,A,target):
      #找到A中第一个大于等于tatget的数字
      start,end = 0,len(A)-1
      while start+1 < end:
         mid = (start+end)//2
         if A[mid] >= target:
            end = mid
         else:
            start = mid
      if A[start] >= target:
         return start
      if A[end] >= target:
         return end
      return end+1
   
   def is_left_closer(self,A,target,left,right):
      if left<0:
         return False
      if right >=len(A):
         return True
      return target-A[left] <= A[right] - target
   
if __name__ == '__main__':
   mylist = []
   cloest = []
   num = int(input("请输入升序排序列表中元素的个数:"))
   for i in range(num):
      data = int(input("请输入元素:"))
      mylist.append(data)
   target = int(input("请输入目标值:"))
   k = int(input("请输入k值:"))
   temp = Solution()
   cloest = temp.kClosestNumbers(mylist,target,k)
   print(cloest)

输出:

请输入升序排序列表中元素的个数:3
请输入元素:1
请输入元素:2
请输入元素:3
请输入目标值:2
请输入k值:3
[2, 1, 3]


请输入升序排序列表中元素的个数:4
请输入元素:1
请输入元素:4
请输入元素:6
请输入元素:8
请输入目标值:3
请输入k值:3
[4, 1, 6]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值