首页 > 编程语言 >算法基础课——基础算法题解

算法基础课——基础算法题解

时间:2024-10-03 17:22:09浏览次数:1  
标签:数列 int 题解 整数 算法 数组 基础课 排序

排序算法(分治)

快速排序:

题面:

给定你一个长度为 \(n\) 的整数数列。

请你使用快速排序对这个数列按照从小到大进行排序。

并将排好序的数列按顺序输出。

输入格式

输入共两行,第一行包含整数 \(n\)。

第二行包含 \(n\) 个整数(所有整数均在 \(1 \sim 10^9\) 范围内),表示整个数列。

输出格式

输出共一行,包含 \(n\) 个整数,表示排好序的数列。

数据范围

\(1 \le n \le 100000\)

输入样例:

5
3 1 2 4 5

输出样例:

1 2 3 4 5

思路:

快速排序是以一种分治思想而实现的。

首先对于一个左端点为 \(l\) 右端点为 \(r\) 的一个数组 \(q\),我们进行一下 3 中操作:

  1. 选定一个分界点:\(q_l,q_r,q_{\frac{l+r}{2}}\),我们先将分界点记作 \(x\)。
  2. 将小于 \(x\) 的数放在 \(q\) 数组的左边,大于 \(x\) 的数放在 \(q\) 数组的右边,等于 \(x\) 的数就不用管,放在那一边都可以。
  3. 递归处理小于 \(x\) 左边数组和大于 \(x\) 右边数组即可。

1 和 3 操作都很轻松,问题就是在 2 步,如何优美地处理后面大小分明的数组。

显然我们可以使用双指针,\(i\) 从前往后找到第一个大于等于 \(x\) 的数,\(j\) 从后往前找到第一个小于等于 \(x\) 的数,如果 \(i<j\) 就将这两个数调换即可。

递归边界?显然就是 \(l=r\) 的时候停止。

AC code

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2e5+100;
int n,q[N];
void quick_sort(int q[],int l,int r){
	if(l>=r) return ;
	int x=q[l+r>>1],i=l-1,j=r+1;
	while(i<j){
		while(q[++i]<x);
		while(q[--j]>x);
        //每次先+1和-1可以确保不会死循环
		if(i<j) swap(q[i],q[j]);
	}
	quick_sort(q,l,j),quick_sort(q,j+1,r);
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr),cout.tie(nullptr);
	cin>>n;
	for(int i=1;i<=n;i++) cin>>q[i];
	quick_sort(q,1,n);
	for(int i=1;i<=n;i++) cout<<q[i]<<' ';cout<<'\n';
	return 0;
}

标签:数列,int,题解,整数,算法,数组,基础课,排序
From: https://www.cnblogs.com/Merge-Change230/p/18445833

相关文章

  • 题解9.29-10.3
    1.MakeitAlternating如果它已经是交替的序列我们就不用管了,最终的目的是把序列变成交替的序列,那么我们可以把连续相同的数全部取出来只留下一个,可以分成几段相同的数,最后的结果就是把这些相同的数全部只保留一个,用排列组合C(m,1);第一个结果很简单,把重复的数加一下即可,后面的答......
  • 代码随想录算法训练营Day2|209.长度最小的子数组 59.螺旋矩阵
    学习资料:https://programmercarl.com/数组总结篇.html#数组的经典题目移动窗格,首尾指针根据条件变化模拟行为,循环不变量(左闭右闭或左闭右开)整个过程保持一致学习记录:209.长度最小的子数组(用while使得尾指针遍历全部;用while实现,当[首:尾]之和>目标值,才移动首指针;为了求最小长度......
  • CF1051F题解
    传送门:https://codeforces.com/problemset/problem/1051/F注意到\(m-n\le20\),求一个连通图中任意两点间最短路,我们不难想到将问题转换到树上。先求出树的任意一颗生成树,此时倍增或者树刨能轻松算出仅含树边的最小路径。而对于非树边,从边的角度显然很难做到,我们不妨从点的角度思......
  • 基础算法--递归算法【难点、重点】
    今天我们即将要开始讲解算法中第一块儿难啃地骨头--递归了,相信有不少小伙伴都因递归而迷惑过,本文就来给大家详细的讲解一下递归到底是什么东西。让你也能瞬间将他打回原形。递归的理解在学习递归之前,我们先理解递归。什么是递归呢?从名字上看我们可以想到递进+回归两个......
  • 算法训练营第七天| 344.反转字符串 541. 反转字符串II 卡码网:54.替换数字
    344.反转字符串状态:成功完成。初始思路:双指针交换位置就可以,如果元素个数为偶数,则刚好交换完最后一组后,left>right;如果元素个数为奇数,交换完最后一组后,left和right同时到达中位数,不需要交换。 541.反转字符串II 状态:没做出来。初始思路:这道题是以上一个题目为基础的,我......
  • 代码随想录算法训练营 | 122.买卖股票的最佳时机II,55. 跳跃游戏,45.跳跃游戏II,1005.K次
    122.买卖股票的最佳时机II题目链接:122.买卖股票的最佳时机II文档讲解︰代码随想录(programmercarl.com)视频讲解︰买卖股票的最佳时机II日期:2024-10-03想法:本来还在想什么时候买股票,结果只需要考虑每天的正收益累加就是最大的收益了。Java代码如下:classSolution{public......
  • 题解:CF724E Goods transportation
    可以在cnblog中阅读。题意有\(n\)座城市,第\(i\)座城市生产了\(p_i\)件货物,最多可以出售\(s_i\)件货物,编号小的城市可以向编号大的城市运输至多\(c\)件货物,问最多能出售多少货物。\(n\le10^4\)。分析乍一看是一个网络流问题,可以这样建图,令\(S\)为源点\(T\)......
  • ABC221G Jumping Sequences 题解
    JumpingSequences把移动的上下左右改成左上、左下、右上、右下(坐标轴旋转\(45\)°)。则最终目的地是\((A+B,A-B)\)。(以前移动的方式是\((\pmd_i,0),(0,\pmd_i)\)。现在每次移动的方式是\((\pmd_i,\pmd_i)\))则\(x,y\)两维可以分开考虑。目标:从\(d_1\simd_n\)中选......
  • Codeforces Round 976 (Div. 2) 题解
    CodeforcesRound976(Div.2)题解2020B一个常见的想法:开关灯=异或,虽然在这道题里没啥用注意到,第i盏灯的按钮被按的次数就是i的除它本身以外的因子个数而完全平方数的因子数为奇数,其他数的因子数为偶数点击查看更多信息#include<bits/stdc++.h>usingnamespacestd;voi......
  • 题解:CF1976D Invertible Bracket Sequences
    可以在cnblog中阅读。题意给一个合法括号序列,问有多少区间\([l,r]\),使得将区间内的每个括号翻转后,括号序列仍合法。分析十分套路地,我们将(看成\(+1\),将)看成\(-1\),则一个括号序列合法的充要条件是转换后的序列满足:前缀和任意位置非负;最后一项为\(0\)。考虑翻转......