首页 > 其他分享 >并归排序的应用 I

并归排序的应用 I

时间:2024-01-27 17:34:05浏览次数:19  
标签:nums int 元素 应用 Pair array 排序 left

目录

1. 题目列表

题目列表:

序号 题目 难度
1 315. 计算右侧小于当前元素的个数 困难

2. 应用

2.1. Leetcode 315. 计算右侧小于当前元素的个数

2.1.1. 题目

315. 计算右侧小于当前元素的个数

给你一个整数数组 nums ,按要求返回一个新数组 counts 。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。

示例 1:

输入:nums = [5,2,6,1]
输出:[2,1,1,0]
解释:

  • 5 的右侧有 2 个更小的元素 (2 和 1)
  • 2 的右侧仅有 1 个更小的元素 (1)
  • 6 的右侧有 1 个更小的元素 (1)
  • 1 的右侧有 0 个更小的元素

2.1.2. 解题思路

首先,我们需要定义一个数据结构 (int value, int index) 来记录每一个元素以及它在数组 \(nums\) 中的索引。

这样,我们可以将原始数组,转换成新的数组 \(array\) ,其中,\(array\) 中的每一个元素都记录了值和索引。

同时,我们需要一个数组 \(count\) 用于记录每一个位置比它小的元素个数。

这里,我们需要借助并归排序的思想,在合并两个有序数组的时候,记录每一个元素右侧比它小的元素个数。

这里,我们以合并两个子数组 \([1,3,5]\)、\([2,4,6,,7]\) 为例来描述查找过程:

image

当我们依次合并两个数组时,当某一个时刻,应该合并 \(temp[i] = 5\) 的时候,可以看出,在原始数组 \(nums\) 中,比 \(5\) 小的元素,就是索引 \(j\) 和索引 \(mid + 1\) 的距离,即 2 个。

image

也就是说,在对 \(nuns[left \cdots right]\) 合并的过程中,每当执行 \(nums[k] = temp[i]\) 时,就可以确定 \(temp[i]\) 这个元素后面比它小的元素个数为 \(j - mid - 1\)。

2.1.3. 代码实现

class Solution {
    private class Pair {
        int val, id;
        Pair(int val, int id) {
            this.val = val;
            this.id = id;
        }
    }

    private Pair[] temp;

    private int[] count;

    public List<Integer> countSmaller(int[] nums) {
        int n = nums.length;
        count = new int[n];
        temp = new Pair[n];
        Pair[] array = new Pair[n];
        for (int i = 0; i < n; i++) {
            array[i] = new Pair(nums[i], i);
        }

        sort(array, 0, n - 1);

        List<Integer> result = new LinkedList<>();
        for (int c : count) {
            result.add(c);
        }
        return result;
    }

    private void sort(Pair[] array, int left, int right) {
        if (left == right) {
            return;
        }

        int mid = left + (right - left) / 2;
        sort(array, left, mid);
        sort(array, mid + 1, right);
        merge(array, left, mid, right);
    }

    private void merge(Pair[] array, int left, int mid, int right) {
        for (int i = left; i <= right; i++) {
            temp[i] = array[i];
        }

        int i = left, j = mid + 1, k = left;
        while (i <= mid && j <= right) {
            if (temp[i].val > temp[j].val) {
                array[k] = temp[j++];
            } else {
                array[k] = temp[i++];
                count[array[k].id] += j - mid - 1;
            }
            k++;
        }

        while (i <= mid) {
            array[k] = temp[i++];
            count[array[k].id] += j - mid - 1;
            k++;
        }

        while (j <= right) {
            array[k++] = temp[j++];
        }
    }
}

参考:

标签:nums,int,元素,应用,Pair,array,排序,left
From: https://www.cnblogs.com/larry1024/p/17991689

相关文章

  • Burp Suite Professional 2024.1.1 (macOS, Linux, Windows) - Web 应用安全、测试和
    BurpSuiteProfessional2024.1.1(macOS,Linux,Windows)-Web应用安全、测试和扫描BurpSuiteProfessional,Test,find,andexploitvulnerabilities.请访问原文链接:https://sysin.org/blog/burp-suite-pro/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgB......
  • kube-vip的实例应用
    kube-vip的实例应用1.简介kube-vip是一个用于Kubernetes集群的轻量级负载均衡器和虚拟IP解决方案,主要用于为Kubernetes控制平面和服务提供高可用性和负载均衡功能。它可以在Kubernetes集群中用作多种角色,包括作为Kubernetes控制平面节点的静态端点或者为Kubernetes......
  • 82. 删除排序链表中的重复元素 II(中)
    目录题目题解:双指针题目给定一个已排序的链表的头head,删除原始链表中所有重复数字的节点,只留下不同的数字。返回已排序的链表。题解:双指针题目给的头节点是第一个元素,处理起来较麻烦(需单独处理头节点);加上习惯用一个空的头节点,所以本题新建了一个虚拟头节点,以便统一......
  • 【树】二叉树的应用 I
    目录1.题目列表2.应用2.1.Leetcode226.翻转二叉树2.1.1.题目2.1.2.解题思路2.1.2.1.方法一:前序遍历2.1.2.2.方法二:后序遍历2.1.3.代码实现2.2.Leetcode116.填充每个节点的下一个右侧节点指针2.2.1.题目2.2.2.解题思路2.2.2.1.方法一:广度优先搜索2.2.2.2.方法二:深......
  • 受欢迎的公司是如何应用增长黑客技术的?
    ​增长黑客对初创公司来说尤其重要,因为他们没有大型老牌公司那样的资源或预算。因此,他们必须找到创新的替代方案来定位自己的增长,增长黑客策略可以让他们快速调整业务和营销战略的某些部分,以便看到他们的底线立即发生变化。这些变化通常是非常小和独特的,但可以推动业务的一些重大......
  • [office] Excel中Frequency函数统计各分数段人数的应用
    通常在在Excel中统计不同分数段或者不同的年龄段人数的方法有利用Countif(X,Y)函数和利用函数Frequency(X,Y),Fequency函数是一个频数函数,它具有统计各区间的频数的功能,使用比较简单,而且它也有两个参数,需要用英语逗号分开,第一个参数"X"是要进行统计的数据,第二个参数"Y"是分组的依据,......
  • C# 面向对象编程进阶:构造函数详解与访问修饰符应用
    C#构造函数构造函数是一种特殊的方法,用于初始化对象。构造函数的优势在于,在创建类的对象时调用它。它可以用于为字段设置初始值:示例获取您自己的C#服务器创建一个构造函数://创建一个Car类classCar{publicstringmodel;//创建一个字段//为Car类创建一个......
  • MFC 根据定时器 ICON 移动 定时器的应用
    ▲会从做向右跑动构造函数:voidCMFCApplication1View::OnDraw(CDC*pDC){CMFCApplication1Doc*pDoc=GetDocument();ASSERT_VALID(pDoc);if(!pDoc)return;//绘制代码pDC->DrawIcon(x1,y1,icon[0]);pDC->DrawIcon(x2,y2+50,......
  • C# 面向对象编程进阶:构造函数详解与访问修饰符应用
    C#构造函数构造函数是一种特殊的方法,用于初始化对象。构造函数的优势在于,在创建类的对象时调用它。它可以用于为字段设置初始值:示例获取您自己的C#服务器创建一个构造函数://创建一个Car类classCar{publicstringmodel;//创建一个字段//为Car类创建一......
  • 断网测试1-拓扑排序-Timeline G
    洛谷P6145第1题   TimelineG查看测评数据信息输入格式  输出格式  输入/输出例子1输入:4 10 31 2 3 41 2 52 4 23 4 4  输出:1638  样例解释无   第b次挤奶在a几挤奶结束至少x天后结束,所以用拓扑跟奖金很......