3.9《LeetCode零基础指南》第五讲排序API学习反思

这篇博客介绍了三种排序算法:快速排序、堆排序和归并排序,并提供了对应的C++实现。此外,还讨论了如何在已排序的数组中查找是否存在重复元素的方法,以及解决最大间距问题的思路。这些内容涵盖了数组操作、排序算法和数组间隔分析的基础知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、

三大排序方法:升序

快速排序:

class Solution {
public:
    void quicksort(vector<int>& a,int left,int right){
    if(left>=right)return;
	int i=left-1,j=right+1;
    int mid=(left+right)/2;
    int key=a[mid];
    while(i<j)
    {
        while(a[++i]<key);
        while(key<a[--j]);
        if(i<j)swap(a[i],a[j]);
    }
    quicksort(a,left,j);
    quicksort(a,j+1,right);
}
vector<int> sortArray(vector<int>& nums) {
    int n=nums.size();
    quicksort(nums,0,n-1);
    return nums;
}
};

堆排序:

1.bulidheap()

首先是建堆,升序排序我们选的是大根堆,必须将父亲左右孩子的最大值给父亲结点,这样只要将最大的nums[0]与末尾的数交换即可实现堆排序;

2.解释其中几个变量,bulidheap()中的len值,在heapsort排序中,每提出一个大根堆中的nums[0]放在结尾

void buildheap(vector<int> &nums,int i,int len)
{
    int bigest=i;
    int leftchild=2*i+1;
    int rightchild=2*i+2;
    int n=nums.size();
    if(leftchild<len && nums[bigest]<nums[leftchild])
        bigest=leftchild;
    if(rightchild<len && nums[bigest]<nums[rightchild])
        bigest=rightchild;
    if(bigest!=i)
    {
        swap(nums[i],nums[bigest]);
        buildheap(nums,bigest,len);
    }
}
void heapsort(vector<int> &nums,int len)
{
    int i;
    //建大根堆
    for(i=nums.size()/2-1;i>=0;i--)
    {
        buildheap(nums,i,len);
    }
    //排序
    for(i=nums.size()-1;i>0;i--)
    {
        swap(nums[i],nums[0]);
        buildheap(nums,0,i);
    }
}

归并排序:

将数组所有元素分开,后每个分开数组与其同父集的子集排序合并并对原数组覆盖。

void HB(vector<int> &nums,int a[],int left,int right,int mid)
{
    int l=left,r=mid+1,pos=left;
    while(l<=mid&&r<=right)
    {
        if(nums[l]<nums[r])
            a[pos++]=nums[l++];
        else
            a[pos++]=nums[r++];
    }
    while(l<=mid)
        a[pos++]=nums[l++];
    while(r<=right)
        a[pos++]=nums[r++];
    while(left<=right)
    {
        nums[left]=a[left];
        left++;
    }
}
void Divide(vector<int> &nums,int a[],int left,int right)
{
    if(left<right)
    {
        int mid=(left+right)/2;
        Divide(nums,a,left,mid);
        Divide(nums,a,mid+1,right);
        HB(nums,a,left,right,mid);
    }
}
void merge_sort(vector<int> &nums)
{
    // 调用实际的归并排序
    int a[nums.size()];
    Divide(nums, a, 0, nums.size()-1);
}

---------------------------------------------------------------------------------------------------------------------------------

二、

217. 存在重复元素

难度简单650

给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。

示例 1:

输入:nums = [1,2,3,1]
输出:true

示例 2:

输入:nums = [1,2,3,4]
输出:false

示例 3:

输入:nums = [1,1,1,3,3,4,3,2,4,2]
输出:true

我的方法:排序求相邻数是否相同

void quick_sort(vector<int> &nums,int left,int right)
    {
        if(left>=right)return;
        int l=left-1;
        int r=right+1;
        int mid=(left+right)/2;
        int key=nums[mid];
        while(l<r)
        {
            while(key>nums[++l]);
            while(key<nums[--r]);
            if(l<r)swap(nums[l],nums[r]);
        }
        quick_sort(nums,left,r);
        quick_sort(nums,r+1,right);
    }
    void sortArray(vector<int>& nums) {
        int n=nums.size();
        quick_sort(nums,0,n-1);
    }
    bool containsDuplicate(vector<int>& nums) {
        sortArray(nums);
        for(int i=1;i<nums.size();i++)
        {
            if(nums[i]==nums[i-1])return true;
        }
        return false;
    }

直接调用函数:

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        int n = nums.size();
        for (int i = 0; i < n - 1; i++) {
            if (nums[i] == nums[i + 1]) {
                return true;
            }
        }
        return false;
    }
};

---------------------------------------------------------------------------------------------------------------------------------

三、

164. 最大间距

难度困难458

给定一个无序的数组 nums,返回 数组在排序之后,相邻元素之间最大的差值 。如果数组元素个数小于 2,则返回 0 。

您必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。

示例 1:

输入: nums = [3,6,9,1]
输出: 3
解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。

示例 2:

输入: nums = [10]
输出: 0
解释: 数组元素个数小于 2,因此返回 0。

代码未完善

int maximumGap(vector<int>& nums)
{
    if(nums.size()<=1)return 0;
    int MAX = 2147483647;
    int MIN = -2147483647;
    int Maxnum=MIN;
    int Minnum=MAX;
    for(int i=0;i<nums.size();i++)
    {
        Maxnum=max(nums[i],Maxnum);
        Minnum=min(nums[i],Minnum);
    }
    if(Maxnum==Minnum)return 0;

    int tongmax[nums.size()-1];
    int tongmin[nums.size()-1];
    int interval=ceil((Maxnum-Minnum)/(nums.size()-1));
    for(int i=0;i<nums.size()-2;i++)
    {
        tongmax[i]=-1;
        tongmin[i]=Maxnum;
    }
    for(int i=0;i<nums.size();i++)
    {
        int id=(nums[i]-Minnum)/interval;
        if(nums[i]==Maxnum||nums[i]==Minnum)continue;
        tongmax[id]=max(nums[i],tongmax[id]);
        tongmin[id]=min(nums[i],tongmin[id]);
    }
    int MaxGap=0,premax=Minnum;
    for(int i=0;i<nums.size()-1;i++)
    {
        if(tongmax[i]=-1)continue;
        MaxGap=max(MaxGap,tongmin[i]-premax);
        premax=tongmax[i];
    }
    MaxGap=max(MaxGap,Maxnum-premax);
    return MaxGap;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值