刷题小分队——第二周

二分法

1、题目地址(69. x 的平方根)

https://leetcode-cn.com/problems/sqrtx/

题目描述

实现 int sqrt(int x) 函数。

计算并返回 x 的平方根,其中 x 是非负整数。

由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

示例 1:

输入: 4
输出: 2


示例 2:

输入: 8
输出: 2
说明: 8 的平方根是 2.82842..., 
     由于返回类型是整数,小数部分将被舍去。

代码

  • 语言支持:Java

Java Code:

class Solution {

    public int mySqrt3(int x) {
        int l = 0, r = x, ans = -1;
        while (l <= r) {
            int mid = l + (r - l) / 2;
            if ((long) mid * mid <= x) {
                ans = mid;
                l = mid + 1;
            } else {
                r = mid - 1;
            }
        }
        return ans;
    }


    public int mySqrt2(int x) {
        if( x <= 1){
            return x;
        }
        int left = 1;
        int right = x;
        int mid = left + ((right - left)>>1);
        while(left <= right){
            if( (long)mid*mid > x ){
                right = mid - 1;
                mid = left + ((right - left)>>1);
            }
            else if ( (long)mid*mid < x ){
                left = mid + 1;
                mid = left + ((right - left)>>1);       
            }
            else{
                return mid;
            }
        }
        return mid;
    }


    public int mySqrt(int x) {
        if( x <= 1){
            return x;
        }
        for(long i=0; i<=x-1; i++){
            if( i*i <= x && (i+1)*(i+1) > x ){
                return (int)i;
            }
        }
        return 1;
    }



}

复杂度分析

令 n 为数组长度。

  • 时间复杂度:O(logn)
  • 空间复杂度:O(1)

2、题目地址(374. 猜数字大小)

https://leetcode-cn.com/problems/guess-number-higher-or-lower/

题目描述

猜数字游戏的规则如下:

每轮游戏,我都会从 1 到 n 随机选择一个数字。 请你猜选出的是哪个数字。
如果你猜错了,我会告诉你,你猜测的数字比我选出的数字是大了还是小了。

你可以通过调用一个预先定义好的接口 int guess(int num) 来获取猜测结果,返回值一共有 3 种可能的情况(-1,1 或 0):

-1:我选出的数字比你猜的数字小 pick < num
1:我选出的数字比你猜的数字大 pick > num
0:我选出的数字和你猜的数字一样。恭喜!你猜对了!pick == num

返回我选出的数字。

 

示例 1:

输入:n = 10, pick = 6
输出:6


示例 2:

输入:n = 1, pick = 1
输出:1


示例 3:

输入:n = 2, pick = 1
输出:1


示例 4:

输入:n = 2, pick = 2
输出:2


 

提示:

1 <= n <= 231 - 1
1 <= pick <= n

代码

  • 语言支持:Java

Java Code:

/** 
 * Forward declaration of guess API.
 * @param  num   your guess
 * @return 	     -1 if num is lower than the guess number
 *			      1 if num is higher than the guess number
 *               otherwise return 0
 * int guess(int num);
 */

public class Solution extends GuessGame {
    public int guessNumber(int n) {
        int left = 1, right = n,  mid = left + ((right - left)>>1);
        while(left <= right){
            if( guess(mid) == 1 ){
                left = mid + 1;
                mid = left + ((right - left)>>1);
            }
            else if( guess(mid) == -1 )
            {
                right = mid - 1;
                mid = left + ((right - left)>>1);
            }
            else{
                return mid;
            }
        }
        return mid;
    }
}

复杂度分析

令 n 为数组长度。

  • 时间复杂度:O(logn)
  • 空间复杂度:O(1)

3、有序矩阵中第 K 小的元素

[https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix/]

题目描述

给你一个 n x n 矩阵 matrix ,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素。
请注意,它是 排序后 的第 k 小元素,而不是第 k 个 不同 的元素。

 

示例 1:

输入:matrix = [[1,5,9],[10,11,13],[12,13,15]], k = 8
输出:13
解释:矩阵中的元素为 [1,5,9,10,11,12,13,13,15],第 8 小元素是 13


示例 2:

输入:matrix = [[-5]], k = 1
输出:-5


 

提示:

n == matrix.length
n == matrix[i].length
1 <= n <= 300
-109 <= matrix[i][j] <= 109
题目数据 保证 matrix 中的所有行和列都按 非递减顺序 排列
1 <= k <= n2

思路

代码

  • 语言支持:Java

Java Code:

class Solution {
    public int kthSmallest(int[][] matrix, int k) {
        int left = matrix[0][0];
        int n = matrix.length;
        int right = matrix[n-1][n-1];
        
        while( left < right ){
            int num = 0;
            int mid = ( left + right ) / 2;
            // 开始统计 小于等于mid 的数量
            for(int i=0; i<n; i++){
                for(int j=n-1; j>=0; j--){
                    if( matrix[j][i] <= mid){
                        num += (j+1);
                        break;
                    }
                }
            }
            // 统计完 小于等于mid 的数量 
            if( num >= k ){
                // 缩小范围
                right = mid;
            }
            else{
                // num小于k  要增大范围,就是增大mid,所以要增加left+right的值,增大left即可
                left = mid + 1;// 不加1的话,如果左右是11 13,答案正好是12的话,那不是一直在这循环了
            }

        }

        return right;


    }


    public int kthSmallest2(int[][] matrix, int k) {
        int n = matrix.length;
        int left = matrix[0][0];
        int right = matrix[n - 1][n - 1];
        while (left < right) {
            int mid = left + ((right - left) >> 1);
            if (check(matrix, mid, k, n)) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return left;
    }

    public boolean check(int[][] matrix, int mid, int k, int n) {
        int i = n - 1;
        int j = 0;
        int num = 0;
        while (i >= 0 && j < n) {
            if (matrix[i][j] <= mid) {
                num += i + 1;
                j++;
            } else {
                i--;
            }
        }
        return num >= k;
    }
}

复杂度分析

令 n 为数组长度。

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值