5.LeetCode刷题记录[排序]排序部分题目

 所有的题集:5.LeetCode刷题记录[排序]排序部分题目_foolish的博客-CSDN博客

关键点:对数组中的数字以字符串的形式进行组合排序,例如[x,y,z] (y+x).compareTo(x+y);根据要求看x在前还是y在前。这道题是y+x这样的形式,形成升序排序。通过两个数字的字符串进行组合排序,可以得到最大值。

class Solution {
    public String largestNumber(int[] nums) {
        Queue<String> pq = new PriorityQueue<String>((x,y)->(x+y).compareTo(y+x));
        for (int i : nums) {
            pq.offer(String.valueOf(i));
        }
        String res = "";
        while(pq.size()>0){
            res += pq.poll();
        }
        if(res.charAt(0) == '0') return "0";//特殊情况
        return res;
    }

剑指 Offer 45. 把数组排成最小的数(类似)

class Solution {
    public String minNumber(int[] nums) {
        // Queue<String> queue = PriorityQueue<String>((x,y)->(x+y).compareTo(y+x));
        Queue<String> queue = new PriorityQueue<String>((x,y)->(x+y).compareTo(y+x));
        for(int i:nums){
            queue.offer(String.valueOf(i));
        }
        String res = "";
        while(queue.size()>0){
            res += queue.poll();
        }
        // if(res.charAt(0)=='0') return "0";
        return res;
    }
}

349. 两个数组的交集(这道题感觉是用Set方便一些)前面已经做过了 就不在这提了

75. 颜色分类(所有的排序方法都能通过过一遍,类似于912)

56. 合并区间icon-default.png?t=LBL2https://link.zhihu.com/?target=https%3A//leetcode-cn.com/problems/merge-intervals/

class Solution {
    public int[][] merge(int[][] intervals) {
        if (intervals.length == 0) {
            return new int[0][2];
        }
        Arrays.sort(intervals,new Comparator<int[]>(){
            public int compare(int[] interval1,int[] interval2){
                return interval1[0] - interval2[0];
            }
        });
        List<int[]> merged = new ArrayList<int[]>();
        for (int i = 0; i < intervals.length; i++) {
            int left = intervals[i][0];
            int right = intervals[i][1];
            //a[i].end<a[j].start(a[i] 和 a[j] 不能合并)
            //a[j].end<a[k].start(a[j] 和 a[k] 不能合并)
            //a[i].end≥a[k].start(a[i] 和 a[k] 可以合并)
            if(merged.size()==0||merged.get(merged.size()-1)[1]<left){
                merged.add(new int[]{left,right});
            }else{
                merged.get(merged.size()-1)[1] = Math.max(merged.get(merged.size()-1)[1],right);
            }
        }
        return merged.toArray(new int[merged.size()][]);
    }
}

253. 会议室 IIicon-default.png?t=LBL2https://link.zhihu.com/?target=https%3A//leetcode-cn.com/problems/meeting-rooms-ii(这是一道VIP题 网上能搜到)

给定一个会议时间安排的数组,每个会议时间都会包括开始和结束的时间 [[s1,e1],[s2,e2],…] (si < ei),为避免会议冲突,同时要考虑充分利用会议室资源,请你计算至少需要多少间会议室,才能满足这些会议安排。

示例 1:
输入: [[0, 30],[5, 10],[15, 20]]
输出:
输入: [[7,10],[2,4]]
输出: 1

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/meeting-rooms-ii

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

import java.util.LinkedList;
class Solution {
    public int minMeetingRooms(int[][] intervals) {
        if(intervals == null || intervals.length == 0){
            return 0;
        }
        Arrays.sort(intervals,(o1,o2)->o1[0]-o2[0]);
        PriorityQueue<Integer> queue = new PriorityQueue<>((o1,o2)->o1-o2);
        queue.offer(intervals[0][1]);
        for(int i = 1;i < intervals.length;i++){
            if(intervals[i][0]>=queue.peek()){
                queue.poll();
            }
            queue.offer(intervals[i][1]);
        }
        return queue.size();
    }
}

56. 合并区间icon-default.png?t=LBL2https://link.zhihu.com/?target=https%3A//leetcode-cn.com/problems/merge-intervals/(和上一题有异曲同工之处)

class Solution {
    public int[][] merge(int[][] intervals) {
        if (intervals.length == 0) {
            return new int[0][2];
        }
        Arrays.sort(intervals,new Comparator<int[]>(){
            public int compare(int[] interval1,int[] interval2){
                return interval1[0] - interval2[0];
            }
        });
        List<int[]> merged = new ArrayList<int[]>();
        for (int i = 0; i < intervals.length; i++) {
            int left = intervals[i][0];
            int right = intervals[i][1];
            //a[i].end<a[j].start(a[i] 和 a[j] 不能合并)
            //a[j].end<a[k].start(a[j] 和 a[k] 不能合并)
            //a[i].end≥a[k].start(a[i] 和 a[k] 可以合并)
            if(merged.size()==0||merged.get(merged.size()-1)[1]<left){
                merged.add(new int[]{left,right});
            }else{
                merged.get(merged.size()-1)[1] = Math.max(merged.get(merged.size()-1)[1],right);
            }
        }
        return merged.toArray(new int[merged.size()][]);
    }
}

总结:253是统计数量,用优先队列很方便,因为他不需要管区间的开始,56题返回的是区间,他需要考虑区间的开始。

1353. 最多可以参加的会议数目icon-default.png?t=LBL2https://link.zhihu.com/?target=https%3A//leetcode-cn.com/problems/maximum-number-of-events-that-can-be-attended/

class Solution {
    public int maxEvents(int[][] events) {
        //首先排序:开始时间小的在前。这样是方便我们顺序遍历,把开始时间一样的都放进堆
        Arrays.sort(events, (o1, o2) -> o1[0] - o2[0]);
        //小顶堆
        PriorityQueue<Integer> pq = new PriorityQueue<>();
        //结果、开始时间、events下标、有多少组数据
        int res = 0, index = 1, i = 0, n = events.length;
        while (i < n || !pq.isEmpty()) {
            //将start相同的会议都放进堆里
            while (i < n && events[i][0] == index ) {
                pq.offer(events[i++][1]);
            }
            //pop掉当前天数之前的
            while (!pq.isEmpty() && pq.peek() < index ) {
                pq.poll();
            }
            //统计参与的会议数
            if (!pq.isEmpty()) {
                pq.poll();
                res++;
            }
            last++;
        }
        return res;
    }
}

剑指 Offer 51. 数组中的逆序对

官方解答:数组中的逆序对 - 数组中的逆序对 - 力扣(LeetCode) (leetcode-cn.com)

315. 计算右侧小于当前元素的个数(做这道题得先看看前面这道题)

官方题解:计算右侧小于当前元素的个数 - 计算右侧小于当前元素的个数 - 力扣(LeetCode) (leetcode-cn.com)

总结:两道题得难度在于处理大数组得情况,意思就是时间复杂度得问题。

767. 重构字符串icon-default.png?t=LBL2https://link.zhihu.com/?target=https%3A//leetcode-cn.com/problems/reorganize-string/(感觉我的解决思路跟排序无关)

class Solution {
    public String reorganizeString(String s) {
        char[] sChar = s.toCharArray();
        int[] sCharCount = new int[26];
        for (int i = 0; i < sChar.length; i++) {
            sCharCount[sChar[i]-'a'] += 1;
        }
        //判断最大重复的字母是不是大于一字符长度的一般
        //多写几组例子可以发现+1/2之后 会有一个不能重新排布的阈值
        int threshold = (s.length()+1)/2;
        int temp = 0;;
        int max = 0;

        for (int i = 0; i < sCharCount.length; i++) {
            if (sCharCount[i] > max) {
                max = sCharCount[i];
                temp = i;
                //如果出现次数最多的那个字符的数量大于阈值,说明他不能使得
                // 两相邻的字符不同,直接返回空字符串即可
                if (max > threshold)
                    return "";
            }
        }
        //后面就随意排布就行
        //偶数序号先放字母数多的
        int index = 0;
        char[] res = new char[s.length()];
        while(sCharCount[temp]-->0){
            res[index] = (char)('a'+temp);
            index += 2;
        }
        //其余的字母也是间隔放
        for (int i = 0; i < sCharCount.length; i++) {
            while(sCharCount[i]-->0){
                if(index>=res.length){
                    index = 1;
                }
                res[index] = (char)(i+'a');//先将偶数填满
                index += 2;
            }
        }
        return new String(res);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值