力扣记录:剑指offer(6)——JZ53-58

JZ53-I 在排序数组中查找数字 I

  • 先使用二分查找搜索目标数字位置,找到目标数字后再向两边计算目标数字出现的次数(优化:两次二分查找,分别找到左边界和右边界)
    • 时间复杂度O(logn),空间复杂度O(1)
class Solution {
   
    public int search(int[] nums, int target) {
   
        //二分查找,左闭右闭
        int left = 0;
        int right = nums.length - 1;
        int count = 0;
        while(left <= right){
   
            int mid = left + (right - left) / 2;
            if(nums[mid] > target){
   
                right = mid - 1;
            }else if(nums[mid] < target){
   
                left = mid + 1;
            }else{
   
                //向两边搜索
                int i = mid;
                int j = mid;
                count += 1;
                while(i >= 1 && nums[i - 1] == target){
   
                    count++;
                    i--;
                }
                while(j < nums.length - 1 && nums[j + 1] == target){
   
                    count++;
                    j++;
                }
                return count;
            }
        }
        return count;
    }
    //优化
    public int search(int[] nums, int target) {
   
        //二分查找,左闭右闭
        //搜索右边界
        int left = 0;
        int right = nums.length - 1;
        int rightBorder = 0;
        while(left <= right){
   
            int mid = left + (right - left) / 2;
            if(nums[mid] > target){
   
                right = mid - 1;
            }else if(nums[mid] <= target){
   
                left = mid + 1;
            }
        }
        if(left == 0 || nums[left - 1] != target) return 0;  //未搜索到目标值
        rightBorder = left;
        //搜索左边界
        int leftBorder = 0;
        left = 0;
        right = rightBorder;    //左边界肯定在右边界左边
        while(left <= right){
   
            int mid = left + (right - left) / 2;
            if(nums[mid] >= target){
   
                right = mid - 1;
            }else if(nums[mid] < target){
   
                left = mid + 1;
            }
        }
        leftBorder = right;
        return rightBorder - leftBorder - 1;
    }
}

JZ53-II 0~n-1中缺失的数字

  • 二分查找,二分后得到的数需要和下标一致,如果大于下标则向左边搜索(左边缺一位),如果等于下标则向右边搜索
    • 时间复杂度O(logn),空间复杂度O(1)
class Solution {
   
    public int missingNumber(int[] nums) {
   
        //二分查找
        int left = 0;
        int right = nums.length - 1;
        while(left <= right){
   
            int mid = left + (right - left) / 2;
            if(nums[mid] > mid){
   
                right = mid - 1;
            }else{
   
                left = mid + 1;
            }
        }
        return left;
    }
}

JZ54 二叉搜索树的第k大节点

  • 中序遍历(二叉搜索树中序遍历递增),计数返回结果
    • 时间复杂度O(n),空间复杂度O(n)
class Solution {
   
    int res, count; //注意这里使用全局变量不容易混淆
    public int kthLargest(TreeNode root, int k) {
   
        //中序遍历的逆序右中左
        count = 0;
        reverseInorder(root, k);
        return res;
    }
    private void reverseInorder(TreeNode root, int k){
   
        if(root == null) return;
        if(count == k) return;
        reverseInorder(root.right, k);
        count++;
        if(count == k){
   
            res = root.val;
            return;
        }
        reverseInorder(root.left, k);
    }
}

JZ55-I 二叉树的深度

  • 前序遍历或后序遍历,到达叶子节点时计算当前深度
    • 时间复杂度O(n),空间复杂度O(二叉树深度)
class Solution {
   
    int res;
    public int maxDepth(TreeNode root) {
   
        //前序遍历
        res = 0;
        if(root == null) return res;
        preorder(root, 1);
        return res;
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值