• 二分查找之leetcode69求开方+441摆硬币+540有序数组的 Single Element


    leetcode 69

    方法一:袖珍计算器算法

    注意:

    • exp和log前面都要加上math,log
    • 最后判断要是<=而不是<
    • 最后两个int相乘机的用较大的long进行处理
    • 时空复杂度均为O(1)
    class Solution {
        public int mySqrt(int x) {
            if(x==0) return 0;
            int res=(int)Math.exp(0.5*Math.log(x));//这里的Math不要忘记
            return (long)(res+1)*(res+1)<=x?(res+1):res;//这里的long也很容易写错,还有<=
        }
    }

    方法二:二分查找

    • 在循环条件为 l < h,如果 h = mid - 1,会错误跳过查找的数,例如对于数组 [1,2,3],要查找 1,最开始 l = 0,h = 2,mid = 1,判断 key < arr[mid] 执行 h = mid - 1 = 0,此时循环退出,直接把查找的数跳过了。
    • 比较奇怪的是二分法是如何找到,最合适的数值的呢?其实这里k是不可能出现在else里面的,但是左边的范围又是不断靠右,所以ans最后一次更新的值一定就是开方值
    class Solution {
        public int mySqrt(int x) {
            int mid=0,l=0,r=x,ans=-1;//这里r=x-1是错误的
            while(l<=r){
                mid=l+(r-l)/2;
                if((long)mid*mid<=x) {//有乘积的时候记得用long
                    ans=mid;
                    l=mid+1;
                }else r=mid-1;//这两句的顺序不能反
                //其实这里k是不可能出现在else里面的
                //但是左边的范围又是不断靠右,所以ans最后一次更新的值一定就是开方值
            }
            return ans;
        }
    }

     leetcode 441

     注意:

     Math.sqrt()参数是double,而n是int型,这里2n+1/4有可能会超出sqrt函数的参数范围。所以可以用 k = sqrt(2) * sqrt(n+1/8) - 1/2

    • 之所以会超限是由于2*n有可能会超限,导致最终结果为0的情况,所以这里可以像上面一样把2*n分开处理:(int)(Math.sqrt(2) * Math.sqrt(n + 0.125) - 0.5);
    • 第二种方法就是通过对2*n取long保存完整数值用于下面的计算。
    class Solution {
        public int arrangeCoins(int n) {
            return (int)(Math.sqrt((long)2*n+0.25) - 0.5);
            // return (int)(Math.sqrt(2) * Math.sqrt(n + 0.125) - 0.5);
        }
    }

    leetcode 540

    这道题主要是由于数值的排列具有一定的规律性和特色。

    始终让他从两个相同数值的数对的前一个开始进行比较,如果m和m+1的数值相同则,往后继续寻找,也说明前面不存在单个的数

    如果m和m+1的数值不同,则返回m这个数值,说明找到了单数,不断缩小比较范围。

    class Solution {
        public int singleNonDuplicate(int[] nums) {
            int l=0,r=nums.length-1;//注意这里r的取值应该为-1
            while(l<r){
                int m=l+(r-l)/2;
                if(m%2==1) m--;
                if(nums[m]==nums[m+1]) l=m+2;
                else r=m;
            }
            return nums[l];
        }
    }
  • 相关阅读:
    c++ 输出 变量名 字符串(zz.is2120.BG57IV3)
    分页存储过程
    连接字符串
    动软 DBHeper 完全代码
    java 数据库连接字符串
    DOS命令行下常见的错误信息
    点击单元格选择整行,又可编辑单元格
    label里文字中的下划线
    Delphi程序中动态生成控件的方法及应用
    双击dbgrid排序的问题
  • 原文地址:https://www.cnblogs.com/sjh-dora/p/12891721.html
Copyright © 2020-2023  润新知