【LeetCode】Sama的个人记录_43

在这里插入图片描述

class Solution {
	// 思路很简单:二进制1计数 + 重写比较器
	// 麻烦的一点是:比较器的参数需要是T,int[]需要包装成Integer[],然后解包装...
    public int[] sortByBits(int[] arr) {
        Integer[] Arr = Arrays.stream(arr).boxed().toArray(Integer[]::new);
        Arrays.sort(Arr, (o1, o2) -> {
            int cnt1 = countBitOne(o1);
            int cnt2 = countBitOne(o2);
            return cnt1 == cnt2 ? o1 - o2 : cnt1 - cnt2;
        });
        return Arrays.stream(Arr).mapToInt(Integer::intValue).toArray();
    }

    // 计算二进制表示中1的个数
    private int countBitOne(int n){
        int cnt = 0;
        while (n > 0){
            if(n % 2 == 1){
                cnt++;
            }
            n >>= 1;
        }
        return cnt;
    }
}
class Solution {
	// 链式编程
    public int[] sortByBits(int[] arr) {
        Comparator<Integer> myComparator = Comparator.comparingInt(Integer::bitCount).thenComparing(Integer::compare);
        return Arrays.stream(arr).boxed().sorted(myComparator).mapToInt(Integer::intValue).toArray();
    }
}

 
 
 
 
在这里插入图片描述

class Solution {
    /**
     *【HashMap + 冒泡排序】
     * 这道题的思路其实不难,无非就是自定义排序方式————Python在这方面很擅长
     */
    public int[] relativeSortArray(int[] arr1, int[] arr2) {
        Map<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < arr2.length; i++) {
            map.put(arr2[i], i);
        }
        for(int i = 0; i < arr1.length - 1; i++){               // 冒泡趟数
            for(int j = 0; j < arr1.length - 1 - i; j++){       // 冒泡指针
                int n1 = arr1[j];
                int n2 = arr1[j + 1];
                // 以下分三种情况
                if(map.containsKey(n1) && map.containsKey(n2) && map.get(n1) > map.get(n2)){
                    swap(arr1, j, j + 1);
                }else if(!map.containsKey(n1) && map.containsKey(n2)){
                    swap(arr1, j, j + 1);
                }else if(!map.containsKey(n1) && !map.containsKey(n2) && n1 > n2){
                    swap(arr1, j, j + 1);
                }
            }
        }
        return arr1;
    }

    private void swap(int[] arr, int i, int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}
>>> 问题在于......打败了Java的5%.............于是参考评论区高赞,采用了一种特殊的【桶排序】,并追加了优化思路,打败100%
class Solution {
    /**
     *【桶排序】其实是使用了桶的思想,但没有使用区间的思想————【计数排序】
     */
    public int[] relativeSortArray(int[] arr1, int[] arr2) {
        int[] bucket = new int[1001];
        // 遍历arr1,把桶填好
        for(int n : arr1){
            bucket[n]++;
        }
        // 其实在arr1上原地修改就可以,但是用个res逻辑更清晰
        int index = 0;
        int[] res = new int[arr1.length];
        // 遍历arr2,并依据桶来填res数组
        for(int n : arr2){
            while (bucket[n] > 0){
                res[index++] = n;
                bucket[n]--;
            }
        }
        // 遍历桶,把剩下的数追加到res中
        for(int i = 0; i < bucket.length; i++){
            if(index == res.length){
                break;
            }
            while (bucket[i] > 0){
                res[index++] = i;
                bucket[i]--;
            }
        }
        return res;
    }
}
>>> 其实【桶排序(计数排序)】仍可以优化,因为桶的大小是根据题设得出的1001
>>>     1·桶的大小取数的最大值 + 1
>>>     2·不仅找到最大值,还找出最小值————使用【偏移量】的思想继续缩小桶的大小,偏移量的大小即为min

 
 
 
 
在这里插入图片描述

class Solution {
    /**
     * 关键思路:
     *      1·按身高h降序排序,身高h相同的按k升序排序
     *      2·优先排身高高的———为什么呢?因为「后来的矮子,不会破坏已经排好队的高个子的排名的合理性」
     *      3·比如(7,0)(6,1)排好了,再排(5,0)直接排在下表0处,整个队列变为(5,0)(7,0)(6,1)————高个子们依旧合理
     */
    public int[][] reconstructQueue(int[][] people) {
        Arrays.sort(people, ((o1, o2) -> (o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0])));
        List<int[]> res = new ArrayList<>();
        for(int[] arr : people){
            res.add(arr[1], arr);
        }
        return res.toArray(new int[people.length][2]);
    }
}

 
 
 
 
 
 
 
 
 
 
 
 
E N D END END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值