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

句容网站建设开发php网站部署步骤

句容网站建设开发,php网站部署步骤,做彩平的材质网站,简易logo在线设计归并排序巧解逆序对问题&#xff1a;LeetCode 剑指 Offer 51.数组中的逆序对 1. 题目链接 剑指 Offer 51. 数组中的逆序对 题目要求&#xff1a;给定一个整数数组 record&#xff0c;返回数组中逆序对的总数。逆序对定义为 i < j 且 record[i] > record[j]。 2. 题目描述…

归并排序巧解逆序对问题:LeetCode 剑指 Offer 51.数组中的逆序对


1. 题目链接

剑指 Offer 51. 数组中的逆序对
题目要求:给定一个整数数组 record,返回数组中逆序对的总数。逆序对定义为 i < jrecord[i] > record[j]


2. 题目描述
  • 输入:整数数组 record,例如 [7,5,6,4]
  • 输出:逆序对总数,例如 5(对应逆序对:(7,5), (7,6), (7,4), (5,4), (6,4))。
  • 约束条件
    • 0 ≤ 数组长度 ≤ 50000
    • 结果可能很大,需对 1e9+7 取模(本题代码未处理,需根据题目要求补充)。

3. 示例分析

示例
输入:record = [7,5,6,4]
输出:5

分步解析

  1. 分解数组

    • 初始数组分为 [7,5][6,4]
    • 左子数组 [7,5] 的逆序对为 1(7 > 5)。
    • 右子数组 [6,4] 的逆序对为 1(6 > 4)。
  2. 合并过程统计

    • 合并左数组 [5,7] 和右数组 [4,6]
      • 比较 545 > 4 → 逆序对增加 2(左数组剩余元素 5,7 均大于 4)。
      • 比较 565 ≤ 6 → 无新增。
      • 比较 767 > 6 → 逆序对增加 1(左数组剩余元素 7 大于 6)。
    • 合并阶段总逆序对:2 + 1 = 3
  3. 总计1(左) + 1(右) + 3(合并) = 5


4. 算法思路
归并排序与逆序对统计的结合
  1. 分治策略

    • 分解数组为左右子数组,递归计算各自的逆序对数量。
    • 合并时统计跨越左右子数组的逆序对数量。
  2. 合并阶段的关键操作

    • 当左子数组元素 nums[cur1] > nums[cur2] 时,左子数组剩余元素(从 cur1mid)均大于 nums[cur2],逆序对增加 mid - cur1 + 1
步骤拆解
  1. 递归分解:将数组二分至单个元素。
  2. 逆序对累加
    • 左子数组内部逆序对数目。
    • 右子数组内部逆序对数目。
    • 合并时左右之间的逆序对数目。
  3. 合并排序:确保合并后的子数组有序,为后续合并提供正确状态。

5. 边界条件与注意事项
  1. 递归终止条件: 当 left >= right 时,子数组长度为0或1,无逆序对。

  2. 索引越界问题:中间点计算 mid = (left + right) / 2 可能导致溢出,建议改为 left + (right - left) / 2

  3. 临时数组管理: 预分配临时数组 tmp 的空间,避免递归中频繁分配内存。

  4. 稳定性处理:合并时若 nums[cur1] == nums[cur2],优先插入左元素,但逆序对不增加。

  5. 复杂度分析

    • 时间复杂度:O(n log n),归并排序的时间复杂度。
    • 空间复杂度:O(n),临时数组和递归栈空间。

6. 代码实现与解析
class Solution {
public:vector<int> tmp; // 全局临时数组,用于合并阶段int reversePairs(vector<int>& record) {tmp.resize(record.size()); // 预分配空间return mergeSort(record, 0, record.size() - 1);}int mergeSort(vector<int>& nums, int left, int right) {if (left >= right) return 0; // 终止条件:子数组长度为0或1int mid = (left + right) / 2; // 计算中间点int ret = 0;ret += mergeSort(nums, left, mid);    // 左子数组逆序对数目ret += mergeSort(nums, mid + 1, right); // 右子数组逆序对数目// 合并并统计跨左右子数组的逆序对int cur1 = left, cur2 = mid + 1, i = 0;while (cur1 <= mid && cur2 <= right) {if (nums[cur1] <= nums[cur2]) {tmp[i++] = nums[cur1++]; // 左元素小,无逆序对} else {ret += mid - cur1 + 1;   // 统计逆序对tmp[i++] = nums[cur2++];}}// 处理剩余元素(不产生新逆序对)while (cur1 <= mid) tmp[i++] = nums[cur1++];while (cur2 <= right) tmp[i++] = nums[cur2++];// 将排序后的数据复制回原数组for (int j = left; j <= right; j++) {nums[j] = tmp[j - left];}return ret;}
};
代码逐行解析
  1. 全局临时数组 tmp

    • 预分配空间,避免递归中频繁申请内存。
  2. 递归分解与统计

    • mergeSort 返回当前区间的逆序对总数,累加左右子数组的结果。
  3. 合并阶段的核心逻辑

    • 逆序对统计:当 nums[cur1] > nums[cur2] 时,左子数组中剩余元素均构成逆序对,数量为 mid - cur1 + 1
    • 稳定性处理:使用 <= 保证相等元素不触发逆序对统计。
  4. 剩余元素处理

    • 剩余元素直接追加到临时数组,不产生新逆序对。
  5. 数据回写

    • 将临时数组的数据复制回原数组的 [left, right] 区间,确保后续合并正确。

总结

归并排序在合并阶段天然适合统计逆序对:左、右子数组有序时,可以高效计算跨越两部分的逆序对数量。通过分治策略,算法的时间复杂度为 O(n log n),优于暴力法的 O(n²)。代码中需注意中间点计算的潜在溢出问题,以及临时数组的预分配优化。掌握这一方法,可解决多数分治类统计问题(如翻转对、右侧更小元素等)。

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

相关文章:

  • 黄冈网站建设费用阿里云虚拟机搭建wordpress
  • 台州路桥做网站的公司wordpress sql优化
  • 悟空建站是什么wordpress4.9免登陆发布接口
  • 男女做视频网站网页制作培训有前途吗
  • 临沂手机网站ui设计比较成功的网站页面
  • 点图片跳到网站怎么做建立网站谁给你钱
  • 中国站长之家域名查询公司门户网站什么意思
  • 银川网站建设广告公司国内的搜索引擎排名
  • 建立视频网站要多少钱长沙网站建设流程
  • 石家庄房和城乡建设部网站阿里云建站费用
  • 网站建设背景需要写些什么软件怎么看网站的收录
  • 外贸网站模板外贸网站建设石家庄搜索排名提升
  • 做网站大概需要多少钱营销策略分析包括哪些内容
  • 建筑人才网招收土建预算员实学生seo好找工作吗
  • 来雁新城建设投资公司官方网站北京王府井步行街
  • 新网站怎么做才能让搜狗收录开发网站需要时间
  • mvc5网站开发用户注册境外电商有哪些平台
  • c 网站开发视频陕西住房和城乡建设厅官网
  • 织梦网站建设教程手机发布WordPress
  • 平度好的建设网站大连商城网站制作公司
  • 怎么做网站网页做网站的工作有发展空间没有
  • 做app的网站二级造价工程师
  • 网站平台之间的关系网站建设亇金手指下拉排名亅
  • 一个可以做行程的网站wordpress 设计网页
  • 客户网站回访南宁网站seo推广公司
  • 简单的网站建设合同书如何建一个免费网站
  • 想学网站建设 如何开始wordpress获取侧边栏
  • 百度为什么不收录网站的某个版块小吃培训2000元学6项
  • 通过git上传项目到码云和GitHub操作手册
  • 广告公司网站主页设计马鞍山网站建设设计