算法刷题集训第三天--排序

📜个人简介

⭐️个人主页:摸鱼の文酱博客主页🙋‍♂️
🍑博客领域:java编程基础,mysql
🍅写作风格:干货,干货,还是tmd的干货
🌸精选专栏:【Java】【mysql】 【算法刷题笔记】
🎯博主的码云gitee,平常博主写的程序代码都在里面。
🚀支持博主:点赞👍、收藏⭐、留言💬
🍭作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!

题目链接难度
1464. 数组中两元素的最大乘积easy
1636. 按照频率将数组升序排序easy
1287. 有序数组中出现次数超过25%的元素easy
436. 寻找右区间medium

📃1464. 数组中两元素的最大乘积

🎯解题思路

📒思路一:库函数排序

  先用库函数把数据升序排列,取最后两个数字相乘

class Solution {
    public int maxProduct(int[] nums) {
        Arrays.sort(nums);
        return (nums[nums.length-1]-1) * (nums[nums.length-2]-1);
    }
}

📒思路二:遍历

  遍历得到最大的和次大的数

class Solution {
    public int maxProduct(int[] nums) {
        int first = Integer.MIN_VALUE, second = Integer.MIN_VALUE;
        for (int num : nums) {
            if (num > first) {
                second = first;
                first = num;
            } else if (num > second) {
                second = num;
            }
        }
        return (first - 1) * (second - 1);
    }
}

📃1636. 按照频率将数组升序排序

🎯解题思路

📒思路一:哈希+排序

  建立一个大小201的数组(因为数据有负数),将所有数据出现个数存在数组相应下标(nums[i]+100);对出现次数排序,出现次数相同的按frequency[i]的大小降序排序

class Solution {
public int[] frequencySort(int[] nums) {
        int[]frequency=new int[201]; //统计每个数字的频率
        for (int i = 0; i <nums.length ; i++) {
            frequency[nums[i]+100]++;
        }
        List<Integer> list=new ArrayList<>(); //int数组的arrays.sort难以自定义排序,所以转换成Integer装箱类
        for (int i = 0; i < nums.length; i++) {
            list.add(nums[i]);
        }
        list.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                if(frequency[o1+100]!=frequency[o2+100]){
                    return frequency[o1+100]-frequency[o2+100];
                }else {
                    return o2-o1;
                }
            }
        });
        return list.stream().mapToInt(Integer::intValue).toArray();
    }
}

📃1287. 有序数组中出现次数超过25%的元素

🎯解题思路

📒思路一:排序计数

  先把数组元素升序排序,这样一样的数字就都排在一起,用count计数,和前一个数字一样的时候,count++,不一样就置为1;每次count变化后判断是否超过25%

class Solution {
    public int findSpecialInteger(int[] arr) {
        Arrays.sort(arr);
        int count = 1;
        for(int i=1;i<arr.length;i++){
            
            if(arr[i] == arr[i-1]){
                count++;
                if(count*4 > arr.length){
                    return arr[i-1];
                }
            } else{
                count=1;
            }
        }
        return arr[0];
    }
}

📃436. 寻找右区间

🎯解题思路

📒思路一:二分查找+排序

  首先我们可以对区间 i n t e r v a l s intervals intervals 的起始位置进行排序,并将每个起始位置 i n t e r v a l s [ i ] [ 0 ] intervals[i][0] intervals[i][0] 对应的索引 i i i 存储在数组 s t a r t I n t e r v a l s startIntervals startIntervals 中,然后枚举每个区间 i i i 的右端点 i n t e r v a l s [ i ] [ 1 ] intervals[i][1] intervals[i][1],利用二分查找来找到大于等于 i n t e r v a l s [ i ] [ 1 ] intervals[i][1] intervals[i][1]的最小值 v a l val val 即可,此时区间 i i i 对应的右侧区间即为右端点 v a l val val 对应的索引。

class Solution {
    public int[] findRightInterval(int[][] its) {
        int n = its.length;
        int[][] clone = new int[n][2];
        for (int i = 0; i < n; i++) clone[i] = new int[]{its[i][0], i};
        Arrays.sort(clone, (a,b)->a[0]-b[0]);
        int[] ans = new int[n];
        for (int i = 0; i < n; i++) {
            int l = 0, r = n - 1;
            while (l < r) {
                int mid = l + r >> 1;
                if (clone[mid][0] >= its[i][1]) r = mid;
                else l = mid + 1;
            }
            ans[i] = clone[r][0] >= its[i][1] ? clone[r][1] : -1;
        }
        return ans;
    }
}

📒思路二:双指针

在这里插入图片描述

class Solution {
    public int[] findRightInterval(int[][] intervals) {
        int n = intervals.length;
        int[][] startIntervals = new int[n][2];
        int[][] endIntervals = new int[n][2];
        for (int i = 0; i < n; i++) {
            startIntervals[i][0] = intervals[i][0];
            startIntervals[i][1] = i;
            endIntervals[i][0] = intervals[i][1];
            endIntervals[i][1] = i;
        }
        Arrays.sort(startIntervals, (o1, o2) -> o1[0] - o2[0]);
        Arrays.sort(endIntervals, (o1, o2) -> o1[0] - o2[0]);

        int[] ans = new int[n];
        for (int i = 0, j = 0; i < n; i++) {
            while (j < n && endIntervals[i][0] > startIntervals[j][0]) {
                j++;
            }
            if (j < n) {
                ans[endIntervals[i][1]] = startIntervals[j][1];
            } else {
                ans[endIntervals[i][1]] = -1;
            }
        }
        return ans;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值