Leetcode日练5 #658 Find K closest element

解决LeetCode 658题,找到排序数组中与给定值x最接近的K个整数。文章介绍了多种解法,包括使用滑动窗口和双指针,并详细讨论了处理边界和轴选择的问题。最终,作者提供了一个260ms的高效解决方案,通过避免使用指针和边界检查来简化问题。
摘要由CSDN通过智能技术生成

#658 Find K Closest Elements

Given a sorted integer array arr, two integers k and x, return the k closest integers to x in the array. The result should also be sorted in ascending order.

An integer a is closer to x than an integer b if:

  • |a - x| < |b - x|, or
  • |a - x| == |b - x| and a < b

解题思路(pseudocode):

1.用常规的二分法,找到arr里与x相等或离x最近的整数。

2.以这个数为轴,其 idx ± k 后框出备选范围[idx-k: idx+k+1];edge case,可能idx-k后小于0,或者idx+k+1后超出len(arr)。这两种情况取0或者len(arr)-1。取备选范围的所有数与x的差值,以及其原来的idx信息,新生成一个list of tuples。

3.再把这个list根据差值从小到大sorted,组成一个dict,key是差值,val是list of对应的idx。

4.循环这个dict,直到取够k个idx为止。key是从小到大排列的,所以当目前val内的idx个数小于k时,则全部取完。若大于k,则只取部分。取idx的规则是看val这个list有没有被x断开。如果x在val之外或者是头尾,则从x近侧取值。比如,在左侧则从小到大取,在右侧就从大到小取。如果被断开了,就是从断裂处的左侧从大往小取,取完了断裂处左侧的idx再取右侧的。

global arr, k, x, left, right, diff_list

arr = [1,3,3,4,5,7,7,8,8,8]
k = 6
x = 6


# find the closest integer: mid is its index
def find_the_closest_integer(arr, x):
    left, right = 0, len(arr) - 1
    while right >= left:
        mid = (left + right) // 2
        # print(mid)
        if arr[mid] == x:
            break
        elif arr[mid] > x:  # x is on the left
            right = mid - 1
        else:  # x is on the right
            left = mid + 1
    print(mid)
    # either mid is the index of the first item after the gap if x is not in the list
    # or the index of the first x in the list
    return mid


# narrow down the scope to find k closest integers
# diff_list is a list of tuple with index and diff
def potential_scope(arr, k, x, mid):
    diff_list = []

    if mid - k >= 0:
        start = mid - k
    else:
        start = 0
    if mid + k + 1 <= len(arr) - 1:
        end = mid + k + 1
    else:
        end = len(arr) - 1
    # print(start, end)
    for i in range(start, end+1):
        diff_list.append((i, abs(arr[i] - x)))
    # print(diff_list)
    return diff_list


# rearrange the scope in a dict based on diff starting from zero
def pool(diff_list):
    pool = sorted(diff_list, key=lambda i: i[1])
    # print(pool)
    pre_diff = []
    pool_dict = {}
    for idx, diff in pool:
        pre_diff.append(diff)

    for i in sorted(set(pre_diff)):  # for each diff
        # print(i)
        pool_dict[i] = []
        for idx, diff in pool:
            if i == diff:
                pool_dict[i].append(idx)

    print(pool_dict)
    return pool_dict


# pick integers from the pool dict
def extract(pool_dict, mid, k):
    num = 0     # counter of qualified indices
    selected = []   # store qualified indices
    for key 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值