LeetCode题目总结:排序技巧||题目汇总

本文介绍了四个关于信息技术的算法问题:寻找数组中的第k个最大元素、找到前k个高频元素、根据字符频率排序字符串以及颜色分类。通过快速排序、小根堆和自定义排序函数等方法,实现了高效解决方案,展示了算法在处理数据和优化问题上的关键作用。
摘要由CSDN通过智能技术生成

目录

 

215.数组中的第k个最大元素

347.前k个高频元素

451.根据字符出现频率排序

75.颜色分类


215.数组中的第k个最大元素

思路:我们可以采用快速排序的分割函数来解决此问题,我们知道,一趟快速排序之后,数组会以某一个值为分割点,使数组的前半部分都小于这个数,后半部分都大于这个数。因此我们可以在每趟的快速排序中,将这个数的最终位置进行返回、判断,来求得在排序之后基准值在第k处的数字即可。

代码实现:

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        if(nums.empty()||k<0||k>nums.size())
            return - 1;
        k = nums.size()-k;
        int index = 0;
        int start = 0;
        int end = nums.size()-1;
        while(1)
        {
            index = quick(nums,start,end);
            if(index==k)
                break;
            else if(index<k)
                start = index +1;
            else 
                end = index -1;
        }
        return nums[index];


    }
    //快排分割函数
    int quick(vector<int>&nums,int i,int j)
    {
        int start = i;
        int end = j;
        int temp =  nums[start];
        while(start<end)
        {
            while(nums[end]>temp&&start<end)
            {
                --end;
            }
            if(start<end)
            {
                nums[start]=nums[end];
                ++start;
            }
            while(nums[start]<temp&&start<end)
            {
                ++start;
            }
            if(start<end)
            {
                nums[end]=nums[start];
                --end;
            }
        }
        nums[start] = temp;
        return start;
    }
};

347.前k个高频元素

思路:这个问题和topK问题一样,我们可以先用map表等相关容器对每个数字出现的次数进行统计,然后巧妙的构造一个容量为K的小根堆来求出前k个出现次数最多的元素。

代码实现:

class Solution {
public:
    template<typename T>
    class Greater
    {
        public:
        bool operator()(T a,T b)
        {
            return a.second>b.second;
        }
    };
    vector<int> topKFrequent(vector<int>& nums, int k) {
        //统计频率
        map<int,int> m;
        for(auto e: nums)
        {
            auto it = m.find(e);
            if(it==m.end())
            {
                m.insert(make_pair(e,0));
            }
            else
            {
                it->second++;
            }
        }
        using type = pair<int,int>;
        //构建小根堆
        priority_queue<type,vector<type>,Greater<type>> que;
        auto it = m.begin();
        while(k&&it!=m.end())
        {
            que.push(*it);
            ++it;
            --k;
        }
        while(it!=m.end())
        {
            if(it->second >que.top().second)
            {
                que.pop();
                que.push(*it);
            }
            ++it;
        }
        vector<int> v;
        while(!que.empty())
        {
            v.push_back(que.top().first);
            que.pop();
        }
        return v;
        
    }
};

451.根据字符出现频率排序

思路:对于此问题,我们可以先统计每个字符出现的次数,然后按照次数进行排序,最后输出即可。这里巧妙的使用了函数对象来作为排序中的比较方式,当然也可以用lambda表达式来替代。

代码实现:

class Solution {
public:
    template<typename T>
    class Greater
    {
        public:
        bool operator()(T &a,T& b)
        {
            return a.num>b.num;
        }
    };
    struct Node
    {
        Node(char c,int n = 0)
        {
            ch = c;
            num = n;
        }
        char ch;
        int num;
    };
    string frequencySort(string s) {
        map<char,int> m;
        //统计次数
        for(auto e: s)
        {
            auto it = m.find(e);
            if(it==m.end())
                m.insert(make_pair(e,1));
            else
                it->second++;
        }
        vector<Node> v;
        for(auto e:m)
        {
            v.push_back(Node(e.first,e.second));
        }
        sort(v.begin(),v.end(),Greater<Node>());
        string res;
        for(auto e:v)
        {
            for(int n = 0;n<e.num;++n)
                res += e.ch;
        }
        return res;
    }
};

75.颜色分类

思路:这个问题其实也就使一个排序的问题,就是将0,1,2按照顺序排好,由于只有三个数字,因此我们可以投机取巧,在O(n)的时间复杂度内完成排序算法。具体见代码。

代码实现:

class Solution {
public:
  
    void sortColors(vector<int>& nums) {
        
       int zero = -1,one = 0,two = nums.size();
       while(one<two)
       {
           if(nums[one] ==0)
           {
               swap(nums,++zero,one++);
           }
           else if(nums[one]==2)
           {
               swap(nums,one,--two);
           }
           else
           {
               ++one;
           }
       }
    }
   void swap(vector<int>&nums,int i,int j)
   {
       int temp = nums[i];
       nums[i]= nums[j];
       nums[j] = temp;
   }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值