力扣 排序专题

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

https://leetcode-cn.com/problems/kth-largest-element-in-an-array/
快速选择算法的模板。其本质就是快速排序思想。
就是根据要找的元素位置可以优化掉快速排序一边区间的过程

class Solution {
    public int quick_sort(int[] nums, int l, int r, int k) {
        if (l == r) return nums[k];
        int x = nums[l + r >> 1], i = l - 1, j = r + 1;
        while (i < j) {
            do i++; while (nums[i] > x);//比x大的放左边,这样当下标为k时就是第K大的元素
            do j--; while (nums[j] < x);//因此可以推出如果题目是求k小元素 这两行大于小于换一下就是了
            if (i < j) swap(nums, i, j);
        }
        if (k <= j) return quick_sort(nums, l, j, k);//如果此时k在左边区间 那只需要对左区间进行后续操作
        else return quick_sort(nums, j + 1, r, k);
    }

    public int findKthLargest(int[] nums, int k) {
        return quick_sort(nums, 0, nums.length - 1, k - 1);
    }

    void swap(int a[], int i, int j) {
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }
}

附上C++快速排序模板:

void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int i = l - 1, j = r + 1, x = q[l + r >> 1];
    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j) swap(q[i], q[j]);
    }
    quick_sort(q, l, j), quick_sort(q, j + 1, r);
}

347. 前 K 个高频元素

https://leetcode-cn.com/problems/top-k-frequent-elements/
类似计数排序的思想

import java.util.HashMap;
import java.util.Map;

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        int[] res = new int[k];    // 结果数组
        HashMap<Integer, Integer> cnt=new HashMap<Integer, Integer>();
        for(int i:nums){
            cnt.put(i,cnt.getOrDefault(i,0)+1);
            //如果map没有对应关系就默认值为0+1=1赋值进去
            //如果有就在基础上加一
            //实现了统计出现次数的功能
        }
        int maxTimes = 0;    // 出现最多的元素的出现次数
        // 找出出现次数最多的元素出现的次数
        for(Map.Entry<Integer, Integer> entry : cnt.entrySet()){
            if(entry.getValue() > maxTimes){
                maxTimes = entry.getValue();
            }
        }
        // 按出现次数从大到小添加到结果数组
        while(k > 0){
            for(Map.Entry<Integer, Integer> entry : cnt.entrySet()){
                if(entry.getValue() == maxTimes){
                    res[k - 1] = entry.getKey();
                    k--;
                }
            }
            maxTimes--;
        }
        return res;
    }
}

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

https://leetcode-cn.com/problems/sort-characters-by-frequency/
核心思想在于构建了一个桶数组,记录了出现对应数组下标次数的元素有哪些

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class Solution {
    public String frequencySort(String s) {
        HashMap<Character,Integer> map =new HashMap<>();
        for(char c:s.toCharArray())
            map.put(c,map.getOrDefault(c,0)+1);
        // 构造一个桶的集合(即一系列桶),桶的个数为 s 的长度 +1,因为 buckets[0] 没有意义
        // 目的是将出现频率为 i 的字符放到第 i 个桶里(即 buckets[i])
        List<Character>[] buckets = new List[s.length() + 1];
        for(char key:map.keySet()){
            int value=map.get(key);
            if(buckets[value]==null){
                buckets[value]=new ArrayList<Character>();
            }
            buckets[value].add(key);
        }
        StringBuilder res = new StringBuilder();
        for (int i = buckets.length - 1; i > 0; --i) {
            // 遍历每个桶
            if (buckets[i] != null) {
                // 如果桶里有字符
                for (char j : buckets[i]) {
                    // 遍历桶里的每个字符
                    for (int k = i; k > 0; --k) {
                        // 字符出现了几次就向 res 中添加几次该字符
                        res.append(j);
                    }
                }
            }
        }
        return res.toString();
    }
}

75. 颜色分类

https://leetcode-cn.com/problems/sort-colors/description/

此题关于奇葩,完美解法大概是3指针思路
其实扫描一遍统计012的次数 然后输出就好了 要求太奇葩不放代码了

posted @ 2021-02-26 15:40  一个经常掉线的人  阅读(134)  评论(0)    收藏  举报