惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Martin Fowler
Martin Fowler
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
M
MIT News - Artificial intelligence
F
Fortinet All Blogs
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog
Microsoft Azure Blog
Microsoft Azure Blog
I
InfoQ
Microsoft Security Blog
Microsoft Security Blog
N
Netflix TechBlog - Medium
G
Google Developers Blog
L
LangChain Blog
腾讯CDC
大猫的无限游戏
大猫的无限游戏
U
Unit 42
Google DeepMind News
Google DeepMind News
人人都是产品经理
人人都是产品经理
罗磊的独立博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
小众软件
小众软件
The GitHub Blog
The GitHub Blog
博客园_首页
GbyAI
GbyAI

博客园 - NickyYe

DYNAMIC LINK LIBRARY - DLL 分布式系统中Unique ID 的生成方法 205. Isomorphic Strings 201. Bitwise AND of Numbers Range 189. Rotate Array 187. Repeated DNA Sequences 167. Two Sum II - Input array is sorted Convert BST to Greater Tree Uncommon Words from Two Sentences Path Sum III Delete Node in a BST Sliding Window Maximum C++ TUTORIAL - MEMORY ALLOCATION - 2016 多线程 Console Event Handling SetConsoleCtrlHandler() -- 设置控制台信号处理函数 SetConsoleCtrlHandler 处理控制台消息 总结open与fopen的区别 LevelDB
Find K Closest Elements
NickyYe · 2018-10-25 · via 博客园 - NickyYe

https://leetcode.com/problems/find-k-closest-elements/description/

Given a sorted array, two integers k and x, find the k closest elements to x in the array. The result should also be sorted in ascending order. If there is a tie, the smaller elements are always preferred.

Example 1:

Input: [1,2,3,4,5], k=4, x=3
Output: [1,2,3,4]

Example 2:

Input: [1,2,3,4,5], k=4, x=-1
Output: [1,2,3,4]

Note:

  1. The value k is positive and will always be smaller than the length of the sorted array.
  2. Length of the given array is positive and will not exceed 104
  3. Absolute value of elements in the array and x will not exceed 104

解题思路:

这题首先想到的是分三种情况,

1. x比arr中最小的元素还小,那么显然取arr中前K个。

2. x比arr中最大的元素还大,那么显然去arr中后k个。

3. x在arr的范围中,那么就需要找到最靠近arr的那个点。

如何找最靠近的点,不就是二分查找吗?能找到相等的就是它了,或者就是比他小一点的那个。这里和Search Insert Position类似,却又不同。

然后想到,1和2其实也可以包含在3中了。

这样,找到了这个最靠近的点,如何找其他k-1个?

开始简单的认为贪心往前找,随后剩下的再往后。这样是不对的,什么叫closest?这样假设arr中的数字都是连续的了(相邻的相差1)。

class Solution {
    public List<Integer> findClosestElements(int[] arr, int k, int x) {
        List<Integer> res = new ArrayList<Integer>();
        
        // 找到x所在的index,或者比他小的那个index
        int neareastIndex = findNearestIndex(arr, x);
        
        // 两种情况需要往前移一个
        if (neareastIndex >= arr.length || arr[neareastIndex] > x) {
            if (neareastIndex > 0) {
                neareastIndex--;
            }
        }
        
        int count = 1;
        int index = neareastIndex, left = neareastIndex - 1, right = neareastIndex + 1;
        //res.add(arr[index]);
        while (count < k) {
            if (left >= 0 && right < arr.length) {
                if (x - arr[left] <= arr[right] - x) {
                    //res.add(0, arr[left]);
                    left--;
                } else {
                    //res.add(arr[right]);
                    right++;
                }
            } else if (left >= 0) {
                //res.add(0, arr[left]);
                left--;
            } else {
                //res.add(arr[right]);
                right++;
            }
            count++;           
        }
        
        for (int i = left + 1; i < right; i++) {
            res.add(arr[i]);
        }
        
        return res;
    }
    
    public int findNearestIndex(int[] arr, int target) {
        int left = 0, right = arr.length - 1;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (arr[mid] == target) {
                return mid;
            } else if (arr[mid] > target) {
                right = mid - 1;
            } else if (arr[mid] < target) {
                left = mid + 1;
            }
        }
        return left;
    }
}