每日一题补题记录7

2.14

540. 有序数组中的单一元素

给你一个仅由整数组成的有序数组,其中每个元素都会出现两次,唯有一个数只会出现一次。

请你找出并返回只出现一次的那个数。

你设计的解决方案必须满足 O(log n) 时间复杂度和 O(1) 空间复杂度。

时间复杂度比较难实现,我可以随便写出两种On的

1.哈希表

class Solution {
    public int singleNonDuplicate(int[] nums) {
        HashMap<Integer,Integer>map=new HashMap<>();
        for(int num:nums){
            if(map.containsKey(num)){
                map.remove(num);
            }else{
                map.put(num, 1);
            }
        }
        int ans=0;
        for(int num:map.keySet()){
            ans=num;
        }
        return ans;
    }
}

2.异或

class Solution {
    public int singleNonDuplicate(int[] nums) {
        int ans = 0;
        for(int x : nums){
            ans = ans^x;
        }
        return ans;
    }
}

O(logn)很显然需要二分 ,毕竟二分查找的时间复杂度摆在这,那我们怎么做呢?

注意到一个点,目标数字的下标一定为偶数,如果偶数和他右边的数字相同,证明还没找到目标数字,如果奇数和他左边的数字相同,证明已经过了目标数字,根据这个来二分。

class Solution {
    public int singleNonDuplicate(int[] nums) {
        int n = nums.length;
        int l = 0, r = n - 1;
        //r为结果位置
        while (l < r) {
            int mid = l + r >> 1;
            //注意偶数考虑右边,奇数考虑左边
            if (mid % 2 == 0) {
                //如果还没到目标数,取右半部分
                if (mid + 1 < n && nums[mid] == nums[mid + 1]) l = mid + 1;
                else r = mid;
                //奇数位
            } else {
                //已经过了目标数,取左半部分
                if (mid - 1 >= 0 && nums[mid - 1] == nums[mid]) l = mid + 1;
                else r = mid;
            }
        }
        return nums[r];
    }
}

2.15

1380. 矩阵中的幸运数

给你一个 m * n 的矩阵,矩阵中的数字 各不相同 。请你按 任意 顺序返回矩阵中的所有幸运数。

幸运数是指矩阵中满足同时下列两个条件的元素:

在同一行的所有元素中最小
在同一列的所有元素中最大


显然这个幸运数只有一个或者零个,我们可以用两轮遍历,第一轮统计每行最小的数和每列最大的数,用row和col两个数组统计,第二轮遍历,如果matrix[i][j]==row[i]&&matrix[i][j]==col[j],证明该数字符合幸运数特征

class Solution {
    public List<Integer> luckyNumbers (int[][] matrix) {
        int m=matrix.length,n=matrix[0].length;
        List<Integer>ans=new ArrayList<>();
        int[]row=new int[m],col=new int[n];
        Arrays.fill(row, Integer.MAX_VALUE);
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                row[i]=Math.min(row[i],matrix[i][j]);
                col[j]=Math.max(col[j],matrix[i][j]);
            }
        }
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(matrix[i][j]==row[i]&&matrix[i][j]==col[j]){
                    ans.add(matrix[i][j]);
                }
            }
        }
        return ans;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值