只做了第1、2题;
1.力扣 6056. 字符串中最大的 3 位相同数字
思路:就是在遍历字符串的过程中,找到符合条件的“优质整数”,并且记录整数的数字大小,后面如果还有碰到,选取更大的数就行。主要考察对字符串的操作,还有字符、int、string相互转换等操作。
学到的点:
·取string中的字符以及char转int:
char c=num.charAt(i);
int intNum=c-'0';
·char转string:
String.valueOf(c);
·string转int:
Integer.parseInt(str);
·String的compareTo()方法:
返回值是整型,它是先比较对应字符的大小(ASCII码顺序),如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的长度差值,如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至比较的字符或被比较的字符有一方结束。
如果参数字符串等于此字符串,则返回值 0;
如果此字符串小于字符串参数,则返回一个小于 0 的值;
如果此字符串大于字符串参数,则返回一个大于 0 的值。
String a = "abcde";
String b = "abcdez";
String c = "abcdeyzq";
String d = "1ab";
String e = "czgagaze";
String f="two";
String g = "three";
System.out.println( a.compareTo(b) ); // -1 (前面相等,a长度小1)
System.out.println( a.compareTo(c) ); // -3 (前面相等,a长度小3)
System.out.println( a.compareTo(d) ); // 48 ("a"的ASCII码是97,"1"的的ASCII码是49,所以返回48)
System.out.println( a.compareTo(e) ); // -2 ("a"的ASCII码是97,"c"的ASCII码是99,所以返回-2)
System.out.println( f.compareTo(g) );//15(第一个相等比较第二个第二个数不等,w比h大15,所以返回15)
//菜鸡写法
class Solution {
public String largestGoodInteger(String num){
int maxValue=-1;
boolean flag=false;
for(int i=0;i<num.length()-2;i++){
char c=num.charAt(i);
int intNum=c-'0';//char转int
if(num.charAt(i)==num.charAt(i+1)&&num.charAt(i)==num.charAt(i+2)){
flag=true;
if(intNum>maxValue)
maxValue=intNum;
}
}
String res="";
if(flag==false)return res;
else{
StringBuilder sb=new StringBuilder();
for(int i=0;i<3;i++)sb.append((char)(maxValue+'0'));
return sb.toString();
}
}
}
//别人的简洁写法
class Solution {
public String largestGoodInteger(String num) {
String res = "";
char[] cs = num.toCharArray();
for (int i=0;i<num.length()-2;i++)
if (cs[i] == cs[i + 1] && cs[i + 1] == cs[i + 2])
//将num的i-i+2位置的连续字符与res内容比较
//若返回值大于0,说明更大,给res赋值
if (num.substring(i, i + 3).compareTo(res) > 0)
res = num.substring(i, i + 3);
return res;
}
}
2.力扣 6057. 统计值等于子树平均值的节点数
最开始只想到层序遍历,层序遍历过程中计算每个结点的平均值,判断是否符合要求。计算平均值也用的是层序遍历,因此时间复杂度很差。
递归方法:
自底向上(后序遍历)传递当前结点的子树结点数量(nodeNum)以及当前结点子树总和,就可以根据这两个值计算当前结点的子树平均值,若等于当前结点值,计数就可以+1。窍门就是每层递归都要更新一个含有两个元素的一维数组,数组第一个元素是当前结点的子树的总结点数(包括当前结点)。第二个元素是当前结点的子树的值的总和(也包括当前结点)。
//菜鸡写法
class Solution {
public int averageOfSubtree(TreeNode root) {
int count=0;
Queue<TreeNode>que=new LinkedList<>();
que.offer(root);
while(!que.isEmpty()){
TreeNode cur=que.poll();
if(compute(cur)==cur.val)count++;
if(cur.left!=null)que.offer(cur.left);
if(cur.right!=null)que.offer(cur.right);
}
return count;
}
//计算当前结点子树平均值(层序)
public int compute(TreeNode root){
int sum=0,countNum=0;
Queue<TreeNode>childQue=new LinkedList<>();
childQue.offer(root);
while(!childQue.isEmpty()){
TreeNode childCur=childQue.poll();
countNum++;
sum+=childCur.val;
if(childCur.left!=null)childQue.offer(childCur.left);
if(childCur.right!=null)childQue.offer(childCur.right);
}
return sum/countNum;
}
}
//后续遍历(自底向上),效率更高
class Solution {
int res=0;
public int averageOfSubtree(TreeNode root) {
dfs(root);
return res;
}
//{nodeNum,sumVal}
public int[] dfs(TreeNode root){
//空结点(最底下)结点数和总和值都是0
if(root==null)return new int[]{0,0};
int[] l=dfs(root.left);
int[] r=dfs(root.right);
int nodeNum=l[0]+r[0]+1;
int sumVal=l[1]+r[1]+root.val;
if(sumVal/nodeNum==root.val)res++;
return new int[]{nodeNum,sumVal};
}
}