给定一个n,代表二叉树节点的个数,返回有多少种不同的二叉树结构
public static int process(int n){
if(n < 0) return 0;
if(n == 0) return 1;
if(n == 1) return 1;
if(n == 2) return 2;
int rest = 0;
for(int leftNum = 0; leftNum <= n;leftNum++){
int leftWays = process(leftNum);
int rightWays = process(n-leftNum-1);
rest += leftWays*rightWays;
}
return rest;
}
public static int numTrees(int n){
if(n < 2) return 1;
int []dp = new int[n+1];
dp[0] = 1;
for(int i =1;i<n+1;i++){//节点个数
for(int j =0;j<=i-1;j++){//左侧j个,右侧n-j个
dp[i] = dp[j]*dp[i-j];
}
}
return dp[n];
}
完整的字符串() (()) (()())都是完整的,给一个不完整的字符串,最少增加几个括号,构成完整的
分析:准备一个count变量,如果出现左括号count++,出现右括号–,如果中途count小于0,说明少count个左括号与之对应,如果遍历完count大于0,说明少count个大于0的右括号与之对应,用一个ans变量记录缺少的左括号,发现count小于0直接通过ans补左括号。所以中途count肯定大于等于0,最后返回ans+count,因为ans的意思是缺少的右括号
public static int needParenthesses(String str){
int count = 0;
int ans = 0;
for(int i = 0; i< str.length();i++) {
if(str.charAt(i) == '('){
count++;
}else{//右括号的情况
if(count ==0){
ans++;
}else{
count--;
}
}
}
return ans+count;
}
给定一个数组arr,求差值为k的去重数字对
public static List<List<Integer>> allPair(int[] arr,int k){
HashSet<Integer> set = new HashSet<>();
for(int i =0;i< arr.length;i++){
set.add(arr[i]);
}
List<List<Integer>> res = new ArrayList<>();
for(Integer cur:set){
if(set.contains(cur + k)){
res.add(Arrays.asList(cur,cur+k));
}
}
return res;
}
给两个集合,从一个集合取一个数到另一个集合,操作后每个集合的平均值要大于之前的操作,如果把集合a中的元素放到集合b中,但集合已经有这个元素了,这种情况a这个元素没有了,b不变,最多可以进行多少次这样的操作
思路:只能从大的平均值的集合,拿到小的集合里去,且拿的数是平均值之间的,不包含边界,在这个范围选最小的,且另一个集合不存在的。
public static int maxOps(int[] arr1,int[] arr2){
double sum1 = 0;
for(int i = 0;i < arr1.length;i++){
sum1 += arr1[i];
}
double sum2 = 0;
for(int i=0;i<arr2.length;i++){
sum2+=arr2[i];
}
if(avg(sum1,arr1.length) == avg(sum2,arr2.length)){
return 0;}
//平均值不相等
int[] arrMore = null;
int[] arrLess = null;
double sumMore = 0;
double sumLess = 0;
if(avg(sum1,arr1.length) > avg(sum2,arr2.length)){
arrMore = arr1;
arrLess = arr2;
sumMore = sum1;
sumLess = sum2;
}else{
arrMore = arr2;
arrLess = arr1;
sumMore = sum2;
sumLess = sum1;
}
Arrays.sort(arrMore);
HashSet<Integer> setLess = new HashSet<>();
for(int num:arrLess){
setLess.add(num);
}
int moreSize = arrMore.length;
int lessSize = arrLess.length;
int ops = 0;//操作了多少次
for(int i =0;i<arrMore.length;i++){
double cur = (double)arrMore[i];
if(cur < avg(sumMore,moreSize)
&& cur > avg(sumLess,lessSize)
&& !setLess.contains(arrMore[i])){
sumMore -= cur;
moreSize--;
sumLess += cur;
lessSize+=;
setLess.add(arrMore[i]);
ops++;
}
}
return ops;
}
public static double avg(double sum,int size){
return sum/(double)(size);
}
最长括号匹配个数
思路:准备一个dp数组,求当前位置匹配的长度,左括号的位置直接设置为0
public static int maxLength(String s){
if(s==null || s.equals("")){
return 0;
}
char[] str = s.toCharArray();
int [] dp = new int[str.length];
int pre = 0;
int res = 0;
for(int i = 1;i<str.length;i++){
if(str[i] == ')'){
pre = i - 1 - dp[i-1];
if(pre >= 0 && str[pre] == '('){
dp[i] = dp[i-1] + 2 + (pre > 0 ? dp[pre-1]:0);
}
}
res = Math.max(res,dp[i]);
}
return res;
}