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