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

推荐订阅源

MyScale Blog
MyScale Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
罗磊的独立博客
博客园 - 叶小钗
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
美团技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell
雷峰网
雷峰网
宝玉的分享
宝玉的分享
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI
爱范儿
爱范儿
小众软件
小众软件
K
Kaspersky official blog
P
Proofpoint News Feed
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - Franky
V
Vulnerabilities – Threatpost
博客园_首页
Microsoft Security Blog
Microsoft Security Blog
C
Cybersecurity and Infrastructure Security Agency CISA
V
V2EX
C
Check Point Blog
S
Schneier on Security
P
Palo Alto Networks Blog
IT之家
IT之家
GbyAI
GbyAI
T
Threat Research - Cisco Blogs
Hugging Face - Blog
Hugging Face - Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Apple Machine Learning Research
Apple Machine Learning Research
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tailwind CSS Blog
Project Zero
Project Zero
Y
Y Combinator Blog
V
Visual Studio Blog
Simon Willison's Weblog
Simon Willison's Weblog
T
Threatpost
Scott Helme
Scott Helme
L
LINUX DO - 热门话题
S
Securelist
C
CERT Recently Published Vulnerability Notes
A
Arctic Wolf
M
MIT News - Artificial intelligence
人人都是产品经理
人人都是产品经理

博客园 - 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;
    }
}