力扣周赛-第 292 场周赛

只做了第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};
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值