【题解】《算法零基础100讲》(第37讲) 排序进阶 - 快速排序

前言

虽然是介绍递归形式的快速排序, 但是做题时都用的C++ STL的sort(),面试时可得手写啊。

快速排序

递归形式详解快速排序C语言实现

原理

每次找到基准值,以基准值为分界线,左边的值全部比基准值小,右边的值全部比基准值大。

规则

  1. 从右向左找比基准值小的数据,找到后放到左边;
  2. 从左向右找比基准值大的数据,找到后放到右边;
  3. 重复 1、2操作,如果 left == right (下标),循环退出,再将基准值放到nums[left]或nums[right]。

代码实现

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>

static void Quick(int* nums, int left, int right);
static int Partition(int* nums, int left, int right);

void Quick_Sort(int* nums, int numsSize)
{
	assert(nums != NULL);

	Quick(nums, 0, numsSize - 1);
}

static void Quick(int* nums, int left, int right)
{
	if (left < right) 
	{
		int par = Partition(nums, left, right);

		if (left < par - 1)
		{
			Quick(nums, left, par - 1);
		}

		if (par + 1 < right) 
		{
			Quick(nums, par + 1, right);
		}
	}
}
static int Partition(int* nums, int left, int right)
{
	
	int key = nums[left];  

	//重复三个规则
	while (left < right) 
	{
		while (left < right && nums[right] > key) 
			right--;
		if (left == right) 
		{
			break;
		}
		nums[left] = nums[right];  

		while (left < right && nums[left] < key) 
			left++;
		if (left == right) 
		{
			break;
		}
		nums[right] = nums[left]; 
	}

	nums[left] = key; //nums[right] = key

	return left; //return right
}

详细过程可看上面链接的文章。。

习题

539. 最小时间差

原题链接:539. 最小时间差

在这里插入图片描述

分析

做法是

  1. 先申请一个等长的整型数组;
  2. 将原字符串数组中的串依次转为整数存放在新的数组中;
  3. 遍历新数组,找出最小时间差;
  4. 遍历后得出的最小答案,再考虑 00:00 和23:59的情况。

代码

class Solution {
public:
    int findMinDifference(vector<string>& timePoints)
    {
        int n = timePoints.size();
        
        //1
        int timeArray[n];
        memset(timeArray, 0, sizeof(timeArray));
	
		//2
        for (int i = 0; i < n; ++i)
        {
            timeArray[i] = stoi(timePoints[i].substr(0, 2)) * 60 + stoi(timePoints[i].substr(3, 2));
        }
		
		//3
        sort(timeArray, timeArray + n);

        int ans = 1440, tmp = 1440;
        for (int i = 0; i < n - 1; ++i)
        {
            tmp = timeArray[i + 1] - timeArray[i];
            ans = min(tmp, ans);
        }
		
		//4
        int err = 24 * 60 + timeArray[0] - timeArray[n - 1];

        return min(ans, err);
    }
};

对应的四个步骤,很容易理解。。

977. 有序数组的平方

原题链接:977. 有序数组的平方

在这里插入图片描述

分析

先依次平方,再排序

代码

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums)
    {
        int n = nums.size();
        
        for (int i = 0; i < n; ++i)
        {
            nums[i] *= nums[i];
        }

        sort(nums.begin(), nums.end(), less<int>());
        return nums;
    }
};

870. 优势洗牌

原题链接:870. 优势洗牌

在这里插入图片描述

分析

将A、B排序,每次取A B中未使用的最大值进行比较。
但要知道哪个元素未使用,需要记住每个元素的下标。

这里就需要利用C++的 pair

pair可以将 2个数据 组合成 一组数据,两个数据可以分别用pair的 两个公有函数 firstsecond访问。

代码

将nums1和打包后的nums2按照从大到小排序

class Solution {
public:
    vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2)
    {
        int n = nums1.size();
        
        vector<pair<int, int>> sorted(n);
        for (int i = 0; i < sorted.size(); ++i)
        {
            sorted[i] = {nums2[i], i};
        }

        sort(nums1.begin(), nums1.end(), greater<int>());
        sort(sorted.begin(), sorted.end(), [](const auto& a, const auto& b){return a.first > b.first;});

        vector<int> ans(n);
        int left = 0, right = n - 1;

        for (int i = 0; i < n; ++i)
        {
            auto[cur, index] = sorted[i];
            if (nums1[left] <= cur)
            {
                ans[index] = nums1[right--];
            }
            else
            {
                ans[index] = nums1[left++];
            }
        }

        return ans;
    }
};

881. 救生艇

原题链接:881. 救生艇

在这里插入图片描述

在这里插入图片描述

分析

先对所有人的体重进行排序;
那可以以这种方式来做:
首先排除最重的人比救生艇的承重还要重。。。

  1. 如果最轻的人和最重的人体重加起来不超过救生艇的承重,那就可以把他们两个放在一个救生艇上,然后排除这两个人,再从剩下的人里按照这样的方法来;
  2. 如果超过了承重,那就让最重的人独自乘坐一条救生艇,在之后分配时不考虑此人。

实现:
在排序后,利用两个指针,一个指向最轻的人,一个指向最重的,按照上面的方式,遇到情况1,将首指针++, 尾指针–;遇到情况2,只将尾指针-- 。

代码

class Solution {
public:
    int numRescueBoats(vector<int>& people, int limit)
    {  
        sort(people.begin(), people.end(), less<int>());

        int ans = 0;
        int light = 0, heavy = people.size() - 1;

        while (light <= heavy)
        {
            if (people[light] + people[heavy] > limit)
            {
                --heavy;
            }
            else
            {
                ++light;
                --heavy;
            }
            ++ans;
        }

        return ans;
    }
};

end

原文链接:《算法零基础100讲》(第37讲) 排序进阶 - 快速排序

作者:英雄哪里出来

谢谢大家收看~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_索伦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值