CodeTop100 Day23

67、 用Rand7()实现Rand10()

算法的尽头是数学....

已知 rand_N() 可以等概率的生成[1, N]范围的随机数
那么:
(rand_X() - 1) × Y + rand_Y() ==> 可以等概率的生成[1, X * Y]范围的随机数
即实现了 rand_XY()

这就是该题的公式

class Solution extends SolBase {
    public int rand10() {
        while(true) {
            int num = (rand7() - 1) * 7 + rand7(); // 等概率生成[1,49]范围的随机数
            if(num <= 40) return num % 10 + 1; // 拒绝采样,并返回[1,10]范围的随机数
        }
    }
}

优化版本

/**
 * The rand7() API is already defined in the parent class SolBase.
 * public int rand7();
 * @return a random integer in the range 1 to 7
 */
class Solution extends SolBase {
    public int rand10() {
        while (true){
            int num = (rand7() - 1) * 7 + rand7();
            // 如果在40以内,那就直接返回
            if(num <= 40) return 1 + num % 10;
            // 说明刚才生成的在41-49之间,利用随机数再操作一遍
            num = (num - 40 - 1) * 7 + rand7();
            if(num <= 60) return 1 + num % 10;
            // 说明刚才生成的在61-63之间,利用随机数再操作一遍
            num = (num - 60 - 1) * 7 + rand7();
            if(num <= 20) return 1 + num % 10;

        }
    }
}

68、验证二叉搜索数

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isValidBST(TreeNode root) {
        return isvalidhelper(root,Long.MIN_VALUE,Long.MAX_VALUE);
    }
    public boolean isvalidhelper(TreeNode node,long lower,long uppper){
        if(node==null){return true ;}
        if(node.val<=lower||node.val>=uppper){return false;}
        boolean left=isvalidhelper(node.left,lower,node.val);
        boolean right=isvalidhelper(node.right,node.val,uppper);
        return left&&right;
    }
}

简单递归题

69、最大正方形

class Solution {
    public int maximalSquare(char[][] matrix) {
        int max = 0;
        int n = matrix.length;
        int m = matrix[0].length;
        int[][] dp = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (matrix[i][j] == '1') {
                    if (i == 0 || j == 0) {
                        dp[i][j] = 1;
                    } else {
                        dp[i][j] = Math.min(dp[i - 1][j], Math.min(dp[i - 1][j - 1], dp[i][j - 1])) + 1;
                    }
                }
                max = Math.max(max, dp[i][j]);
            }
        }
        return max * max;
    }
}

该题可以用前缀和,二进制运算,动态规划来做

该题的dp定义为以该位置为正方形的右下角能形成的最大正方形的边长

走到i,j位置只需要考虑,该位置左边,上边,斜上边的最小值+1就是边长,每次遍历记录max值,

面积为边长*边长

70、在排序数组中查找元素的第一个和最后一个位置

class Solution {
    public int[] searchRange(int[] nums, int target) {
       int[] result={-1,-1};
       int first=findFirst(nums,target);
       if(first==-1){
        return result;
       }
       int last=findLast(nums,target);
       result[0]=first;
       result[1]=last;
       return result;
    }
    private int findFirst(int []nums,int target){
        int left=0;
        int right=nums.length-1;
        int result=-1;
        while(left<=right){
            int mid=left+(right-left)/2;
            if(nums[mid]==target){
                result=mid;
                right=mid-1;//收缩右边界
            }else if(nums[mid]<target){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return result;
    }
    private int findLast(int[] nums,int target){
        int left=0;
        int right=nums.length-1;
        int result=-1;
        while(left<=right){
            int mid=left+(right-left)/2;
            if(nums[mid]==target){
                result=mid;
                left=mid+1;//收缩左边界
            }else if(nums[mid]<target){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return result;
    }
}

题中要求用logn解决就知道是用二分,但是掌握左右边界很难

71、字符串解码

class Solution {
    public String decodeString(String s) {
      StringBuilder res=new StringBuilder();
      int multi=0; 
       LinkedList<Integer> stack_multi=new LinkedList<>();
       LinkedList<String> stack_res=new LinkedList<>();
       for(Character c:s.toCharArray()){
        if(c=='['){
            stack_multi.addLast(multi);
            stack_res.addLast(res.toString());
            multi=0;
            res=new StringBuilder();
        }else if(c==']'){
            StringBuilder temp=new StringBuilder();
            int cur_multi=stack_multi.removeLast();
            for(int i=0;i<cur_multi;i++)temp.append(res);
            res=new StringBuilder(stack_res.removeLast()+temp);
        }else if(c>='0'&&c<='9') multi=multi*10+Integer.parseInt(c+"");
        else res.append(c);
       }
       return res.toString();
    }
}

使用辅助栈模拟,如3[a2[c]b]-> 3[accb] ->accbaccbaccb

72、搜索二维矩阵||

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
       if(matrix==null||matrix.length==0)return false;
       int m=0;int n=matrix[0].length-1;//m为行,n为列
       while(m<matrix.length&&n>=0){
        if(matrix[m][n]==target){
            return true;
        }else if(matrix[m][n]>target){
            n--;
        }else{
            m++;
        }

       }
        return false;
    }
}

从右上角开始查找,target大于该值,就往下一行该列找,否则就在该行往左边找

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值