首页 > 其他分享 >归并分治

归并分治

时间:2024-12-06 20:33:27浏览次数:5  
标签:归并 right int 分治 mid left

[Algo] 归并分治

1. 经典归并排序

// 1. 经典归并排序
void merge(vector<int> &v, int left, int mid, int right)
{
    vector<int> tmp(v);
    int i = left, j = mid + 1, k = left;
    while (i <= mid && j <= right) tmp[k++] = v[i] <= v[j] ? v[i++] : v[j++];
    while (i <= mid) tmp[k++] = v[i++];
    while (j <= right) tmp[k++] = v[j++];
    v = tmp;
}
void mergeSort(vector<int> &v, int left, int right)
{
    if (left == right) return;
    int mid = (left + right) / 2;
    mergeSort(v, left, mid);
    mergeSort(v, mid + 1, right);
    merge(v, left, mid, right);
}

2. 归并分治

1)思考一个问题在大范围上的答案,是否等于,左部分的答案 + 右部分的答案 + 跨越左右产生的答案

2)计算“跨越左右产生的答案”时,如果加上左、右各自有序这个设定,会不会获得计算的便利性

3)如果以上两点都成立,那么该问题很可能被归并分治解决(话不说满,因为总有很毒的出题人)

小和问题:

// 2. 小和问题
long crossing(vector<int> &v, int left, int mid, int right)
{
    // 统计
    long ans = 0;
    for (int j = mid + 1, i = left, sum = 0; j <= right; j++)
    {
        while (i <= mid && v[i] <= v[j]) sum += v[i++];
        ans += sum;
    }
    // merge
    vector<int> tmp(v);
    int i = left, j = mid + 1, k = left;
    while (i <= mid && j <= right) tmp[k++] = v[i] <= v[j] ? v[i++] : v[j++];
    while (i <= mid) tmp[k++] = v[i++];
    while (j <= right) tmp[k++] = v[j++];
    v = tmp;
    return ans;
}
long smallSum(vector<int> &v, int left, int right)
{
    if (left == right) return 0;
    int mid = (left + right) / 2;
    return smallSum(v, left, mid) + smallSum(v, mid + 1, right) + crossing(v, left, mid, right);
}

标签:归并,right,int,分治,mid,left
From: https://www.cnblogs.com/yaoguyuan/p/18591397

相关文章

  • 递归、分治和动态规划
    递归、分治和动态规划是算法中的三种重要思想,尽管它们有一些相似之处,但在具体实现和应用上有所不同。下面我将逐一讲解这三者的概念和区别。1.递归(Recursion)递归是算法中的一种思想,指的是通过将一个大问题分解为规模较小的相同问题来求解问题。递归通过函数自己调用自己来实现......
  • 蓝桥杯分治
    P1226【模板】快速幂题目描述给你三个整数 ......
  • LeetCode刷题 -- 分治快排
    目录颜色分类题目解析算法原理代码排序数组题目解析算法原理代码数组中第K个最大元素题目解析算法原理代码LCR159.库存管理III题目解析算法原理代码颜色分类题目链接题目解析数组分为三块算法原理1.如果nums[i]==0,++left,i++下标对应元素交换,先+......
  • 排序算法之归并排序
    归并排序归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(DivideandConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。代价是需要额外的内存空间。若将两个有序表合并成一个有序表,称为......
  • 归并排序的学习
    归并排序思想:归并的本质也是分治,不过不同于快速排序,它在将大问题分成小问题之后最后需要将小问题合并成最终的排序结果。#include<iostream>usingnamespacestd;constintN=1e6+10;intn;intq[N],tmp[N];voidmerge_sort(intq[],intl,intr){if(l>=r......
  • 写一个方法实现“归并排序算法”,并解释下时间复杂度和空间复杂度
    functionmergeSort(arr){if(arr.length<=1){returnarr;//递归终止条件:数组长度小于等于1时,已经有序}constmid=Math.floor(arr.length/2);constleft=arr.slice(0,mid);constright=arr.slice(mid);//递归地对左右两部分进行排序c......
  • 算法时间复杂度和空间复杂度计算方法(O(1)、O(n)、O(logn)、O(n^2)、O(n^3 )、O(n!))分
    文章目录时间复杂度与空间复杂度计算方法一、时间复杂度概述1.1时间复杂度的定义1.2常见的时间复杂度-**常数复杂度O(......
  • 数据结构初阶终——七大排序法(堆排序,快速排序,归并排序,希尔排序,冒泡排序,选择排序,插入
    排序1.插入排序2.希尔排序3.冒泡排序4.选择排序(双头排序优化版)5.堆排序6.快速排序1).双指针法2).前后指针法3).非递归法7.归并排序1).递归版本(递归的回退就是归并)2).非递归版本(迭代版本)计算机执行的最多的操作之一就有排序,排序是一项极其重要的技能接下来......
  • 12-15分治法的应用
    分治法的应用前提条件如图:13.二分搜索#include<iostream>usingnamespacestd;constintN=1e6;intn,m;intq[N];//对于二分分界来说左加右减//对于取中值来说,男左女右,男是1,不用+,女需要+1intmain(){cout<<"请输入数组个数以及查寻的数的个数"<<endl;cin>>......
  • CDQ分治
    CDQ分治有n个元素,第i个元素有ai,bi,ci三个属性,设f(i)表示满足aj≤ai且bj≤bi且cj≤ci且j!=i的j的数量。求f数组。解决三维偏序的流程:同样有归并排序和树状数组两种做法,我们这里给出树状数组做法。先按一维属性排序和去重1.假设三维分别是x,y,z,先按x排序。2.......