当前位置: 首页 > news >正文

必刷算法100题之计算右侧小于当前元素的个数

题目链接

315. 计算右侧小于当前元素的
个数 - 力扣(LeetCode)

题目解析

计算数组里面所有元素右侧比它小的数的个数, 并且组成一个数组,进行返回

算法原理

归并解法(分治)

当前元素的后面, 有多少个比我小(降序)

我们要找到第一比左边小的元素, 这样就可以找到一堆比左边小的元素: right - cur2+1

nums[cur1]对应的位置,里面的ret[原始下标]+=right-cur2+1

此时我们就需要找到数组原始的下标,然后把数记上

我们使用一个数组的每一个元素来一一对应记录nums每个元素的下标

然后在每一次归并排序,排完后,下标也跟着变

细节问题, 在创建辅助数组进行合并的时候, 需要创建俩个辅助数组, 一个给nums,一个给index,因为俩个数组是同步改变的

代码编写

class Solution {
    int[] ret;//记录结果
    int[] index; // 标记 nums 中当前元素的原始下标
    int[] tmpIndex;// 记录临时数组的值
    int[] tmpNums;//记录临时下标的值

    public List<Integer> countSmaller(int[] nums) {
        int n = nums.length;
        ret = new int[n];
        index = new int[n];
        tmpIndex = new int[n];
        tmpNums = new int[n];
// 初始化 index 数组
        for (int i = 0; i < n; i++)
            index[i] = i;
        mergeSort(nums, 0, n - 1);
        List<Integer> l = new ArrayList<Integer>();
        for (int x : ret)
            l.add(x);
        return l;
    }

    public void mergeSort(int[] nums, int left, int right) {
        if (left >= right) return;
// 1. 根据中间元素划分区间
        int mid = (left + right) / 2;
// [left, mid] [mid + 1, right]
// 2. 处理左右两个区间
        mergeSort(nums, left, mid);
        mergeSort(nums, mid + 1, right);
// 3. 处理⼀左⼀右的情况
        int cur1 = left, cur2 = mid + 1, i = 0;
        while (cur1 <= mid && cur2 <= right) // 降序排序
        {
            if (nums[cur1] <= nums[cur2]) {
                tmpNums[i] = nums[cur2];
                tmpIndex[i++] = index[cur2++];
            } else {
                ret[index[cur1]] += right - cur2 + 1; // 重点
                tmpNums[i] = nums[cur1];
                tmpIndex[i++] = index[cur1++];
            }
        }
// 4. 处理剩余的排序⼯作
        while (cur1 <= mid) {
            tmpNums[i] = nums[cur1];
            tmpIndex[i++] = index[cur1++];
        }
        while (cur2 <= right) {
            tmpNums[i] = nums[cur2];
            tmpIndex[i++] = index[cur2++];
        }
        for (int j = left; j <= right; j++) {
            nums[j] = tmpNums[j - left];
            index[j] = tmpIndex[j - left];
        }
    }
}

http://www.dtcms.com/a/113284.html

相关文章:

  • 【算法竞赛】状态压缩型背包问题经典应用(蓝桥杯2019A4分糖果)
  • Linux数据库:【数据库基础】【库的操作】【表的操作】
  • [SAP SD] 常用事务码
  • Linux的/proc/sys/net/ipv6/conf/(all,default,interfaceName具体网络接口名称)/ 笔记250405
  • 国产系统统信uos和麒麟v10在线打开word给表格赋值
  • HTTP查询参数示例(XMLHttpRequest查询参数)(带查询参数的HTTP接口示例——以python flask接口为例)flask查询接口
  • ConstructorResolver
  • Day2-2:前端项目uniapp壁纸实战
  • HashMap 底层原理详解
  • C++学习之LINUX网络编程-套接字通信基础
  • JWT认证服务
  • [MySQL初阶]MySQL(9)事务机制
  • 基于springboot+vue的二手车交易系统
  • Supervisor的安装和使用
  • 0101安装matplotlib_numpy_pandas-报错-python
  • Business English Certificates (BEC) 高频词汇学习
  • 将MATLAB神经网络数据转换为C/C++进行推理计算
  • Linux网络状态监控利器:netstat与ping命令详解
  • Java的Selenium的特殊元素操作与定位之select下拉框
  • RocketMQ初认识
  • C,C++语言缓冲区溢出的产生和预防
  • 【2012】【论文笔记】太赫兹波在非磁化等离子体——
  • 【国产突围!致远电子ZXDoc如何打破Vector垄断,成为新能源车研发“神器”?】
  • Xshell Plus 6下载与安装
  • 【机器学习】机器学习工程实战-第4章 特征工程
  • LabVIEW商业软件开发注意问题
  • C语言-基础语法学习
  • 【Linux系统】linux下的软件管理
  • 大数据技术发展与应用趋势分析
  • `use_tempaddr` 和 `temp_valid_lft ` 和 `temp_prefered_lft ` 笔记250405