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大于该值,就往下一行该列找,否则就在该行往左边找