第一题
public class 第一题05 {
public static void main(String[] args) {
int[] res = maxSplitNum("010110001");
System.out.println(res);
}
public static int[] maxSplitNum(String str){
int n = str.length();
char[] arr = str.toCharArray();
int zero = 0;
int one = 0;
HashMap<Integer,HashMap<Integer,Integer>> map = new HashMap<>();
int[] ans = new int[n];
for (int i = 0;i < n;i++){
if (arr[i] == '0'){
zero++;
}else {
one++;
}
if (zero == 0 || one == 0){
ans[i] = i + 1;
continue;
}
int gcd = gcd(zero,one);
int zero_gcd = zero / gcd;
int one_gcd = one / gcd;
if (!map.containsKey(zero_gcd)){
map.put(zero_gcd,new HashMap<>());
}
if (!map.get(zero_gcd).containsKey(one_gcd)){
map.get(zero_gcd).put(one_gcd,1);
}else {
map.get(zero_gcd).put(one_gcd,map.get(zero_gcd).get(one_gcd) + 1);
}
ans[i] = map.get(zero_gcd).get(one_gcd);
}
return ans;
}
public static int gcd(int a,int b) {
return b==0?a:gcd(b, a%b);
}
public static BigInteger gcd(BigInteger a, BigInteger b) {
return b.compareTo(BigInteger.ZERO) == 0 ? a : gcd(b, a.mod(b));
}
}
第二题
思路:单调栈
这里使用char[]数组代替stack栈的作用(更方便)
public class 第二题 {
public static void main(String[] args) {
String res = maxString("babdabddd", 5);
System.out.println(res);
}
public static String maxString(String s,int k){
if (k <= 0 || s.length() < k){
return "";
}
int n = s.length();
char[] str = s.toCharArray();
char[] stack = new char[k];
int index = 0;
for (int i = 0;i < n;i++){
while (index > 0 && stack[index - 1] < str[i] && index + n - i != k){
index--;
}
if (index + n - i == k){
return String.valueOf(stack,0,index) + s.substring(i);
}
stack[index] = str[i];
index++;
}
return String.valueOf(stack,0,k);
}
}
第三题
leetcode300:最长递增子序列
思路:动态规划(O(n * n))
动态规划 + 二分查找(O(n * logn))
public class 第三题05 {
public static int lengthOfLIS(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
int res = 0;
for (int i = 0;i < n;i++){
int l = 0;
int r = res;
while (l < r){
int mid = (l + r) / 2;
if (dp[mid] < nums[i]){
l = mid + 1;
}else {
r = mid;
}
}
dp[l] = nums[i];
if (res == r){
res++;
}
}
return res;
}
}
第四题
思路:二分
public class 第四题05 {
public static void main(String[] args) {
int res = isStepSum(753);
System.out.println(res);
}
public static int isStepSum(int stepSum){
int l = 0;
int r = stepSum;
while (l <= r){
int mid = (l + r) / 2;
if (getStepSum(mid) < stepSum){
l = mid + 1;
}else if (getStepSum(mid) > stepSum){
r = mid - 1;
}else {
return mid;
}
}
return -1;
}
private static int getStepSum(int mid) {
int sum = 0;
while (mid != 0){
sum += mid;
mid = mid / 10;
}
return sum;
}
}
第五题
leetcode45:跳跃游戏2
public class 第五题05 {
public static int jump(int[] nums) {
int n = nums.length;
int count = 0;
int len = 0;
int max = 0;
for (int i = 0;i < n;i++){
max = Math.max(max,i + nums[i]);
if(i == len){
count++;
len = max;
}
}
return count;
}
}
第六题
leetcode : 面试题 08.14. 布尔运算
思路:递归 + 记忆化搜索
public class 第六题05 {
public int countEval(String s, int result) {
if (s == null || s.equals("")){
return 0;
}
int n = s.length();
char[] chars = s.toCharArray();
Info[][] dp = new Info[n][n];
Info info = process(chars,0,n - 1,dp);
return result == 1 ? info.t : info.f;
}
private Info process(char[] chars, int l, int r, Info[][] dp) {
if (dp[l][r] != null){
return dp[l][r];
}
int t = 0;
int f = 0;
if (l == r){
t = chars[l] == '1' ? 1 : 0;
f = chars[l] == '0' ? 1 : 0;
}else {
for (int i = l + 1;i < r;i += 2){
Info left = process(chars,l,i - 1, dp);
Info right = process(chars,i + 1,r, dp);
int left_t = left.t;
int left_f = left.f;
int right_t = right.t;
int right_f = right.f;
if (chars[i] == '&'){
t += left_t * right_t;
f += left_t * right_f + left_f * right_f + left_f * right_t;
}else if (chars[i] == '|'){
t += left_t * right_t + left_t * right_f + left_f * right_t;
f += left_f * right_f;
}else {
t += left_t * right_f + left_f * right_t;
f += left_t * right_t + left_f * right_f;
}
}
}
dp[l][r] = new Info(t,f);
return dp[l][r];
}
class Info{
public int t;
public int f;
public Info(int t,int f){
this.t = t;
this.f = f;
}
}
}
第七题
leetcode:面试题 08.14. 布尔运算
思路:递归 + 记忆化搜索
public class 第七题05 {
public static void main(String[] args) {
double res1 = f1(5, 23, 26);
System.out.println(res1);
double res2 = f2(5, 23, 26);
System.out.println(res2);
double res3 = f3(5, 23, 26);
System.out.println(res3);
}
//暴力递归
public static double f1(int N,int a,int b){
if (N < 1 || a >= b || a < 0 || b < 0){
return 0.0;
}
if (b - a >= N){
return 1.0;
}
return p1(0,N,a,b);
}
private static double p1(int cur, int N,int a, int b) {
if (cur >= a && cur < b){
return 1.0;
}
if (cur >= b){
return 0.0;
}
double w = 0.0;
for (int i = 1;i <= N;i++){
w += p1(cur + i,N,a,b);
}
return w / N;
}
//公式法
public static double f2(int N,int a,int b){
if (N < 1 || a >= b || a < 0 || b < 0){
return 0.0;
}
if (b - a >= N){
return 1.0;
}
return p2(0,N,a,b);
}
private static double p2(int cur, int n, int a, int b) {
if (cur >= a && cur < b){
return 1.0;
}
if (cur >= b){
return 0.0;
}
if (cur == a - 1){
return 1.0 * (b - a) / n;
}
double w = p2(cur + 1,n,a,b) + p2(cur + 1,n,a,b) * n;
if (b - n - 1 > cur){
w -= p2(cur + 1 + n,n,a,b);
}
return w / n;
}
public static double f3(int N,int a,int b){
if (N < 1 || a >= b || a < 0 || b < 0){
return 0.0;
}
if (b - a >= N){
return 1.0;
}
double[] dp = new double[b];
for (int i = a;i < b;i++){
dp[i] = 1.0;
}
if (a - 1 >= 0){
dp[a - 1] = 1.0 * (b - a) / N;
}
for (int i = a - 2;i >= 0 && i >= b - 1 - N;i--){
dp[i] = (dp[i + 1] + dp[i + 1] * N) / N;
}
for (int i = b - 2 - N;i >= 0;i--){
dp[i] = (dp[i + 1] + dp[i + 1] * N - dp[i + 1 + N]) / N;
}
return dp[0];
}
}