jq 改数组的k值_九章算法 | 字节跳动面试题:无序数组K小元素

1d8724ec3d0260a757c17b58243e7306.png

找到一个无序数组中第K小的数。

在线评测地址:LintCode 领扣

样例 1:

输入: [3, 4, 1, 2, 5], k = 3
输出: 3

样例 2:

输入: [1, 1, 1], k = 2
输出: 1

【题解】

最容易想到的就是直接排序,返回第k大的值。时间复杂度是O(nlogn),这里提供O(n)的解法。

这题其实是快速排序算法的变体,通过快速排序算法的partition步骤,可以将小于pivot的值划分到pivot左边,大于pivot的值划分到pivot右边,所以可以直接得到pivotrank。从而缩小范围继续找第k大的值。

partition步骤:

  1. left = startright = endpivot = nums[left]
  2. nums[left] < pivot时,left指针向右移动。
  3. nums[right] > pivot时,right指针向左移动。
  4. 交换两个位置的值,right指针左移,left指针右移。
  5. 直到两指针相遇,否则回到第2步。

每次partition后根据pivot的位置,寻找下一个搜索的范围。

复杂度分析

设数组长度为n

时间复杂度O(n)

  • 对一个数组进行partition的时间复杂度为O(n)
  • 分治,选择一边继续进行partition
  • 所以总的复杂度为T(n) = T(n / 2) + O(n),总时间复杂度依然为O(n)

空间复杂度O(1)

  • 只需要快速选择游标的O(1)额外空间。
public class Solution {
    /**
     * @param k: An integer
     * @param nums: An integer array
     * @return: kth smallest element
     */
    public int kthSmallest(int k, int[] nums) {
        int n = nums.length;
        // 数组从0开始标号,要传k - 1
        return partition(nums, 0, n - 1, k - 1);
    }
    private int partition(int[] nums, int start, int end, int k) {
        int left = start, right = end;
        int pivot = nums[left];
        
        while (left <= right) {
            while (left <= right && nums[left] < pivot) {
                left++;
            }
            while (left <= right && nums[right] > pivot) {
                right--;
            }
            if (left <= right) {
                swap(nums, left, right);
                left++;
                right--;
            }
        }
        
        // 如果第 k 小在右侧,搜索右边的范围,否则搜索左侧。
        if (k <= right) {
            return partition(nums, start, right, k);
        }
        if (k >= left) {
            return partition(nums, left, end, k);
        }
        return nums[k];
    }
    private void swap(int[] nums, int x, int y) {
        int temp = nums[x];
        nums[x] = nums[y];
        nums[y] = temp;
    }
}

更多题解参见:九章算法

内容概要:该题库专为研究生入学考试计算机组成原理科目设计,涵盖名校考研真题、经典教材课后习题、章节题库和模拟试题四大核心模块。名校考研真题精选多所知名高校的计算机组成原理科目及计算机联考真题,并提供详尽解析,帮助考生把握考研命题趋势与难度。经典教材课后习题包括白中英《计算机组成原理》(第5版)和唐朔飞《计算机组成原理》(第2版)的全部课后习题解答,这两部教材被众多名校列为考研指定参考书目。章节题库精选代表性考题,注重基础知识与重难点内容,帮助考生全面掌握考试大纲要求的知识点。模拟试题依据历年考研真题命题规律和热门考点,精心编制两套全真模拟试题,并附标准答案,帮助考生检验学习成果,评估应试能力。 适用人群:计划参加研究生入学考试并报考计算机组成原理科目的考生,尤其是需要系统复习和强化训练的学生。 使用场景及目标:①通过研读名校考研真题,考生可以准确把握考研命题趋势与难度,有效评估复习成效;②通过经典教材课后习题的练习,考生可以巩固基础知识,掌握解题技巧;③通过章节题库的系统练习,考生可以全面掌握考试大纲要求的各个知识点,为备考打下坚实基础;④通过模拟试题的测试,考生可以检验学习成果,评估应试能力,为正式考试做好充分准备。 其他说明:该题库不仅提供详细的题目解析,还涵盖了计算机组成原理的各个方面,包括计算机系统概述、数据表示与运算、存储器分层、指令系统、中央处理器、总线系统和输入输出系统等。考生在使用过程中应结合理论学习与实践操作,注重理解与应用,以提高应试能力和专业知识水平。
### 使用 `jq` 命令从 JSON 数组中删除元素 为了实现从 JSON 数组中移除特定元素的功能,可以利用 `jq` 提供的选择器和过滤功能来构建相应的表达式。对于想要基于某些条件筛选并排除掉不满足这些条件的数据项而言,在 `jq` 中可以通过逻辑运算符以及内置函数达成目的。 当目标是从数组里依据某个键对的标准剔除不符合要求的对象时,下面给出了一种通用模式: 假设有一个包含多个对象的 JSON 数组,并且希望根据某字段的具体取决定是否保留该条目。如果是要去除所有具有指定属性等于特定得成员,则可采用如下方式编写命令[^1]: ```bash jq 'map(select(.field != "value"))' file.json ``` 这里 `.field` 表示用于判断的关键字名称,而 `"value"` 则代表期望匹配从而予以清除的内容。此语句会遍历整个输入序列中的每一个实体,仅挑选那些对应位置上存储的信息不是所提供参数的情况加入最终的结果集内。 另外一种情况是直接按照索引来操作,即明确知道要删去第几个项目的时候,可以用 del 函数配合路径描述完成任务: ```bash jq 'del(.array[index])' ``` 其中 index 是待处理元素的位置编号(注意这里的计数是从零开始)。上述例子适用于已知确切下标的简单情形;不过更常见的是动态确定哪些成分应该被舍弃的情形,这时还是推荐使用前一类方法更为灵活高效。 #### 实际案例演示 考虑到实际应用场景可能涉及复杂嵌套结构或多种不同类型的组合在一起形成列表形式存在,因此提供一个具体实例帮助更好地理解如何运用以上介绍的技术手段解决问题。 假设有这样一个 JSON 文件 content.json ,里面记录了一些文章的相关信息构成的一个集合: ```json [ {"title": "Article One", "url": "/path/to/article-one"}, {"title": "Article Two", "url": "/path/to/article-two"}, {"title": "Article Three", "url": "/path/to/article-three"} ] ``` 现在的需求是要把所有标题中含有单词 "Two" 的条目都去掉。那么就可以执行这样的 shell 指令来进行转换: ```bash cat content.json | jq 'map(select(.title | contains("Two") | not))' ``` 这段脚本的作用就是读入原始数据流之后,经过一系列映射变换只留下那些不含有所述特征的文章详情作为新的输出展示出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值