题目描述
给定一个整数数组,给定一个值K,这个值在原数组中一定存在,要求把数组中小于K的元素放到数组的左边,大于K的元素放到数组的右边,等于K的元素放到数组的中间,最终返回一个整数数组,其中只有两个值,分别是等于K的数组部分的左右两个下标值。
例如,给定数组:[2, 3, 1, 9, 7, 6, 1, 4, 5],给定一个值4,那么经过处理原数组可能得一种情况是:[2, 3, 1, 1, 4, 9, 7, 6, 5],需要注意的是,小于4的部分不需要有序,大于4的部分也不需要有序,返回等于4部分的左右两个下标,即[4, 4]
算法的处理过程
此处的图片来源于以下博客
https://www.jianshu.com/p/356604b8903f
非常感谢原作者对本题目算法的详细剖析,因为发现原文有些地方存在少许错误,本文再次更正,并用c++对原算法进行重写,并将测试结果附在博客的最后部分
less 用于记录小于 4 的区域的右下标,初始为-1,代表不存在
more 用于记录大于 4 区域的左下标,初始为9,代表不存在
L 用于正在遍历的元素的下标,初始值为0
从 arr[L] 即 arr[0] 开始遍历数组
如果 arr[L] < 4, 交换 arr[++ less] 和 arr[L++] 的值
如果 arr[L] > 4, 交换 arr[–more] 和 arr[L] 的值
如果 arr[L] = 4, 不交换,L++,直接遍历下一个值
当 L >= more,退出循环。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void Flag(vector<int> &nums,int P) {
int less = -1;
int more = nums.size();
int L = 0;
int R = nums.size() - 1;
while (L < more) {
if (nums[L] < P) {
swap(nums[++less], nums[L++]);
}
else if (nums[L] > P) {
swap(nums[--more], nums[L]);
}
else {
L++;
}
}
}
int main() {
vector<int> nums = { 2,3,1,9,7,6,1,4,5 };
int P = 4;
cout << "排序前:" << endl;
for (const int i : nums)cout << i << " ";
cout << endl << "排序后:" << endl;
Flag(nums, P);
for (const int i : nums)cout << i << " ";
return 0;
}
博客中特别标注的博客作者以及原文再次进行标明出处,如果原作者有任何问题,请联系文人删除。
作者:CoderJed
链接:https://www.jianshu.com/p/356604b8903f