排序衍生题目

leetcode56合并区间

在这里插入图片描述
在这里插入图片描述

  • 贪心思想
class Solution {
    public int[][] merge(int[][] intervals) {
        Arrays.sort(intervals, Comparator.comparingInt(o -> o[0]));
        int first = intervals[0][0];
        int points = intervals[0][1];
        List<int[]> list = new ArrayList<>();
        int i = 0;
        while (true) {
            while (i < intervals.length && intervals[i][0] <= points) {
                points = Math.max(points, intervals[i][1]);
                i++;
            }
            list.add(new int[]{first, points});
            if (i == intervals.length) break;
            first = intervals[i][0];
            points = intervals[i][1];
        }
        return list.toArray(new int[list.size()][2]);
    }
}

leetcode315计算右侧小于当前元素的个数🔐

在这里插入图片描述
在这里插入图片描述

  • 归并排序和数组索引,通过比较元素变换索引来进行模拟排序

代码讲解戳这里

class Solution {
    private int[] index;
    private int[] helper;
    private int[] count;

    public List<Integer> countSmaller(int[] nums) {
        int N = nums.length;
        List<Integer> res = new ArrayList<>(N);
        index = new int[N];
        helper = new int[N];
        count = new int[N];
        for (int i = 0; i < index.length; i++) {
            index[i] = i;
        }
        merge(nums, 0, nums.length - 1);
        for (int value : count) {
            res.add(value);
        }
        return res;
    }

    private void merge(int[] nums, int s, int e) {
        if (s >= e) return;
        int mid = (s + e) >> 1;
        merge(nums, s, mid);
        merge(nums, mid + 1, e);
        process(nums, s, mid, e);
    }

    private void process(int[] nums, int s, int mid, int e) {
        int i = s, j = mid + 1;
        int hi = s;
        while (i <= mid && j <= e) {
            if (nums[index[i]] <= nums[index[j]]) {// 右侧出
                helper[hi++] = index[j++];
            } else {// 左侧出 计数
                count[index[i]] += e - j + 1;
                helper[hi++] = index[i++];
            }
        }
        while (i <= mid) helper[hi++] = index[i++];//左侧出
        while (j <= e) helper[hi++] = index[j++];// 右侧出
        System.arraycopy(helper, s, index, s, e + 1 - s);
    }
}

leetcode179最大数

在这里插入图片描述
在这里插入图片描述

class Solution {
    public String largestNumber(int[] nums) {
        String[] str = new String[nums.length];
        for (int i = 0; i < str.length; i++) str[i] = String.valueOf(nums[i]);
        Arrays.sort(str, ((o1, o2) -> (o2 + o1).compareTo(o1 + o2)));
        StringBuffer res = new StringBuffer();
        for (String s : str) res.append(s);
        return res.toString().charAt(0) == '0' ? "0" : res.toString();
    }
}

leetcode220存在重复元素 III🔐

在这里插入图片描述
在这里插入图片描述

class Solution {
    public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
        int n = nums.length;
        TreeSet<Long> ts = new TreeSet<>();
        for (int i = 0; i < n; i++) {
            Long u = nums[i] * 1L;
            // 从 ts 中找到小于等于 u 的最大值(小于等于 u 的最接近 u 的数)
            Long l = ts.floor(u);
            // 从 ts 中找到大于等于 u 的最小值(大于等于 u 的最接近 u 的数)
            Long r = ts.ceiling(u);
            if(l != null && u - l <= t) return true;
            if(r != null && r - u <= t) return true;
            // 将当前数加到 ts 中,并移除下标范围不在 [max(0, i - k), i) 的数(维持滑动窗口大小为 k)
            ts.add(u);
            if (i >= k) ts.remove(nums[i - k] * 1L);
        }
        return false;
    }
}

leetcode324摆动排序 II🔐

在这里插入图片描述
在这里插入图片描述

class Solution {
    public void wiggleSort(int[] nums) {
        if (nums.length <= 1) return;
        Arrays.sort(nums);
        int[] temp = new int[nums.length];
        int k = nums.length - 1;
        for (int i = 1; i < nums.length; i += 2) {
            temp[i] = nums[k--];
        }
        for (int i = 0; i < nums.length; i += 2) {
            temp[i] = nums[k--];
        }
        System.arraycopy(temp,0,nums,0,temp.length);
    }
}

leetcode57插入区间


在这里插入图片描述

class Solution {
    public int[][] insert(int[][] intervals, int[] newInterval) {
        int idx = 0;
        List<int[]> res = new ArrayList<>();
        while (idx < intervals.length && intervals[idx][1] < newInterval[0]) { //寻找需要合并的区间
            res.add(intervals[idx]);
            idx++;
        }

        while (idx < intervals.length && intervals[idx][0] <= newInterval[1]) { //待合并区间头小于当前区间尾
            newInterval[0] = Math.min(newInterval[0], intervals[idx][0]); //更新待合并区间头
            newInterval[1] = Math.max(newInterval[1], intervals[idx][1]); //更新待合并区间尾
            idx++;
        }
        res.add(newInterval);// 加入合并区间
        while (idx < intervals.length) { // 加入剩余区间
            res.add(intervals[idx++]);
        }
        return res.toArray(new int[res.size()][]);
    }
}

leetcode274H指数

在这里插入图片描述
在这里插入图片描述

class Solution {
    public int hIndex(int[] citations) {
        int[] res = new int[1001];
        for (int val : citations) {
            res[val]++;
        }
        for (int i = 999; i >= 0; i--) {
            res[i] += res[i + 1];
        }
        for (int i = 1000; i >= 0; i--) {
            if (res[i] >= i) return i;
        }
        return 0;
    }
}

leetcode164最大区间🔐

在这里插入图片描述
在这里插入图片描述

class Solution {
    public int maximumGap(int[] nums) {
        if (nums == null || nums.length < 2) {
            return 0;
        }
        int len = nums.length;
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        for (int value : nums) {
            min = Math.min(min, value);
            max = Math.max(max, value);
        }
        if (min == max) {
            return 0;
        }
        // 记录桶中是否存在值
        boolean[] hasNum = new boolean[len + 1];
        int[] maxs = new int[len + 1];
        int[] mins = new int[len + 1];
        int bid = 0;
        // 由于多一个桶,那么其中一个桶定为空,最大差值定比一个桶的范围大
        // 最大差值定比的两个数定在不同的桶中,选出每个桶中的最大值最小值
        for (int num : nums) {
            bid = bucket(num, len, min, max);// 该数应该在桶中的下标
            // 更新桶中的最大最小值
            mins[bid] = hasNum[bid] ? Math.min(mins[bid], num) : num;
            maxs[bid] = hasNum[bid] ? Math.max(maxs[bid], num) : num;
            hasNum[bid] = true;
        }
        int res = 0;
        int lastMax = maxs[0];

        // 最大差值定存在于不同的桶中
        for (int i = 1; i <= len; i++) {
            if (hasNum[i]) {
                res = Math.max(res, mins[i] - lastMax);
                lastMax = maxs[i];// 记录该桶的最大值,用于后续不同桶的最大差值的比较
            }
        }
        return res;
    }

    // 计算桶的下标索引
    public static int bucket(long num, long len, long min, long max) {
        return (int) ((num - min) * len / (max - min));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

「 25' h 」

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

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

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

打赏作者

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

抵扣说明:

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

余额充值