Leetcode刷题 2021.03.13

Leetcode447 回旋镖的数量

给定平面上 n 对 互不相同 的点 points ,其中 points[i] = [xi, yi] 。回旋镖 是由点 (i, j, k) 表示的元组 ,其中 i 和 j 之间的距离和 i 和 k 之间的距离相等(需要考虑元组的顺序)。

返回平面上所有回旋镖的数量。

印象里好像做过这题了,今天又发现没有提交过,(lll¬ω¬)。题目还是比较基础的,数量小于500,一定就是O(n^2)的解法了。要求距离相等,那一定是记录之前算过的距离了,考虑用hashmap实现。

class Solution {
    public int numberOfBoomerangs(int[][] points) {
        if (points.length < 3) return 0;
        int n = points.length, res = 0;
        for(int i = 0; i < n; i++){
            Map<Integer, Integer> map = new HashMap<>();
            for(int j = 0;j < n; j++){
                if (i == j) continue;
                //记录一下算过的距离,如果有相等的距离就加一
                int distance = (points[i][0] - points[j][0]) * (points[i][0] - points[j][0]) + (points[i][1] - points[j][1]) * (points[i][1] - points[j][1]);
                // System.out.println(distance);
                map.put(distance, map.getOrDefault(distance, 0) + 1);
            }
            //这里等于val * (val - 1),具体用个例子想想就知道了
            for(int val : map.values()){
                res += val * (val - 1);
            }
        }
        return res;
        
    }
}

Leetcode705 设计哈希集合

不使用任何内建的哈希表库设计一个哈希集合(HashSet)。

实现 MyHashSet 类:

void add(key) 向哈希集合中插入值 key 。
bool contains(key) 返回哈希集合中是否存在这个值 key 。
void remove(key) 将给定值 key 从哈希集合中删除。如果哈希集合中没有这个值,什么也不做。

感觉这种设计的题也是蛮多见的,考的最多的应该就是LRU了,然后设计一个hashmap,或者阻塞队列等等。好像看到了14号的每日一题和这个差不多,明天在记录吧。

class Solution {
    List<List<Integer>> edge = new ArrayList<>();
    public int[] loudAndRich(int[][] richer, int[] quiet) {
        int n = quiet.length;
        for(int i = 0; i < n; i++){
            edge.add(new ArrayList<>());
        }
        //先构建边
        for(int[] rich : richer){
            edge.get(rich[1]).add(rich[0]);
        }
        //构建数组,并且初始化为-1
        int[] res = new int[n];
        Arrays.fill(res, -1);
        for(int i = 0; i < n; i++){
        	//从底向上递归
            helper(res, quiet, i);
        }
        return res;

    }

    private int[] helper(int[] res, int[] quiet, int index){
    	//如果已经有结果了,就返回当前的下标和安静值
        if (res[index] != -1) return new int[]{res[index], quiet[res[index]]};
        //如果一个点没有比它更富有的人,那就更新它的结果,并返回它的下标和安静值
        if (edge.get(index).size() == 0){
            res[index] = index;
            return new int[]{index, quiet[index]};
        }
        //否则就进行递归,不断更新结果
        int min = quiet[index];
        res[index] = index;
        for(int i = 0; i < edge.get(index).size(); i++){
            int[] temp = helper(res, quiet, edge.get(index).get(i));
            if (temp[1] < min){
                min = temp[1];
                res[index] = temp[0];
            }
        }
        //最后返回自己的结果就行了
        return new int[]{res[index], min};
    }
}

Leetcode556 下一个更大元素 III

给你一个正整数 n ,请你找出符合条件的最小整数,其由重新排列 n 中存在的每位数字组成,并且其值大于 n 。如果不存在这样的正整数,则返回 -1 。

注意 ,返回的整数应当是一个 32 位整数 ,如果存在满足题意的答案,但不是 32 位整数 ,同样返回 -1 。

这题和31题是一模一样的题,也是字节比较喜欢考的题目吧。想法就是贪心的从后往前选一个比之前大的数,然后交换它们的位置,反转一下顺序就行了。


class Solution {
    public int nextGreaterElement(int n) {
        char[] arr = String.valueOf(n).toCharArray();
        int i = arr.length - 2;
        //从后往前找一个大于前一个元素的数
        while (i >= 0 && arr[i] >= arr[i + 1]){
            i--;
        }
        //如果没有,就说明找不到更大的了
        if (i == -1) return -1;
        int j = arr.length - 1;
        //从后往前找第一个大于索引位置的数
        for(; j > i; j--){
            if (arr[j] > arr[i]){
                break;
            }
        }
        //交换两个数
        swap(arr, i, j);
        //交换之后i位置之后一定是降序排列了,把他们反转成升序排列
        reverse(arr, i + 1, arr.length - 1);
        long sum = 0;
        for(int k = 0; k < arr.length; k++){
            sum = sum * 10 + arr[k] - '0';
        }
        if (sum > Integer.MAX_VALUE) return -1;
        return (int)sum;
        
    }

    private void swap(char[] nums, int i, int j){
        char temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

    private void reverse(char[] nums, int i, int j){
        while (i < j){
            swap(nums, i, j);
            i++;
            j--;
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值