LeetCode第292场周赛(2022-05-08)

6056. 字符串中最大的 3 位相同数字

https://leetcode-cn.com/problems/largest-3-same-digit-number-in-string/
在这里插入图片描述

思路:枚举开始点0-n-3, 判断以开始点为起点的连续3个字符是否一样,一样则更新最大值

class Solution {
    public String largestGoodInteger(String num) {
         int n=num.length();
		 int ans=-1;
		 for(int i=0;i<n-2;i++) {
			 if(num.charAt(i)==num.charAt(i+1)&&num.charAt(i+1)==num.charAt(i+2)){
                int val=Integer.parseInt(num.substring(i,i+3));
			    ans=Math.max(ans, val);
             }
		 }
		if(ans==-1)
			return "";
		else if(ans==0)
			return "000";
		else {
			return ans+"";
		}
    }
}

6057. 统计值等于子树平均值的节点数

在这里插入图片描述

思路:递归计算以每个节点形成的子树的节点数目和节点数值和,当某个节点形成的子树遍历完后,判断是否平均值=节点值,是的话令成员变量ans加一,然后以数组的形式将结点数和数值和返回给上一层递归

class Solution {
    int ans=0;
    public int averageOfSubtree(TreeNode root) {
		if(root==null)
			return 0;
		dfs(root);
		return ans;
	}
	public int[] dfs(TreeNode node) {
		if(node==null)
			return new int[] {0,0};
		int[] leftAns=dfs(node.left);
		int[] rightAns=dfs(node.right);
		int nodes=leftAns[0]+rightAns[0]+1;
		int sum=leftAns[1]+rightAns[1]+node.val;
		if(sum/nodes==node.val)
			ans++;
		return new int[] {nodes,sum};
		
	}
}

6058. 统计打字方案数

https://leetcode-cn.com/problems/count-number-of-texts/
在这里插入图片描述

思路:对于按键7和9,上面有4个字符,考虑有连续的n个7,则这n个7可以形成多少种字母的组合?

由于最多可以选取4个连续的数字形成1个字符,所以对于7个9而言,当前的数字个数是n. n个数字可以构成的字符总和为: f[n]=f[n-1]+f[n-2]+f[n-3]+f[n-4] 因为新加入一个字符,该字符可以和之前的n-1个字符形成一个组合,也可以和之前的n-2个字符形成一个组合…(类似于跳台阶问题)

同理,对于除7和9之外的按键,上面只有3个字符,计算公式为:f[n]=f[n-1]+f[n-2]+f[n-3
计算出给定连续的数字所能形成的字符数目之后,后面只需要统计出每一段连续的字符个数,然后根据组合中的乘法定理对各部分得到的字符数相乘即可

class Solution {
    public int countTexts(String pressedKeys) {
        int n=pressedKeys.length();
        long mod=(long) (1e9+7);
        long[] dp3=new long[100000+1];
        long[] dp4=new long[100000+1];
        dp3[1]=dp4[1]=1;
        dp3[2]=dp4[2]=2;
        dp3[3]=dp4[3]=4;
        dp3[4]=7;
        dp4[4]=8;
        for(int i=5;i<=n;i++){
            dp3[i]=(dp3[i-1]+dp3[i-2]+dp3[i-3])%mod;
            dp4[i]=(dp4[i-1]+dp4[i-2]+dp4[i-3]+dp4[i-4])%mod;
        }
        long ans=1;
        int i=0;
        while(i<n){
            int j=i;
            while(j<=n-2&&pressedKeys.charAt(j)==pressedKeys.charAt(j+1))
                j++;
            int cnt=j-i+1;
            if(pressedKeys.charAt(i)=='7'||pressedKeys.charAt(i)=='9')
                ans=ans*dp4[cnt]%mod;
            else
                ans=ans*dp3[cnt]%mod;
            j++;
            i=j;
        }
        return (int)(ans%mod);
    }
}

6059. 检查是否有合法括号字符串路径

https://leetcode-cn.com/problems/check-if-there-is-a-valid-parentheses-string-path/
在这里插入图片描述
在这里插入图片描述

思路:动态规划

  1. 用一个变量c来来记录当前遍历得到的字符串中左括号和右括号的数量差,遇到左括号c加一,遇到右括号c减一,如果某个时刻c<0, 说明后面无论怎么添加括号都不会形成有效的括号序列,因此只有c>=0时后面才有可能得到一个有效的括号组合,对于右下角的格子(终点),记作其状态为dp[m-1][n-1][c],则最终的路径是否可以得到一个合法的字符串取决于dp[m-1][n-1][0]是否为true

  2. 假设当前位置是(i,j),那么对于当前格子的状态c值的范围是[0,i+1+j+1-1]=[0,i+j-1], 对于某个位置(i,j),它可以从左到右移动得到,也可以从上到下移动得到,根据当前格子是左括号还是右括号决定当前格子c值的变化,更新后的c值如果>=0说明可以继续往下走

class Solution {
    public boolean hasValidPath(char[][] grid) {
        int m=grid.length,n=grid[0].length;
        boolean[][][] dp=new boolean[m][n][m+n];
        if(grid[0][0]==')')
            return false;
        dp[0][0][1]=true;//第一个位置要求是左括号
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                for(int k=0;k<=i+j+1;k++){
                    if(dp[i][j][k]){//当前位置往后遍历可能得到有效的字符串
                        if(i+1<m){//可以往右走
                            int nk=k+(grid[i+1][j]=='('?1:-1);
                            if(nk>=0)//更新后的c值>=0 说明当前位置往后遍历可能得到有效的字符串
                                dp[i+1][j][nk]=true;
                        }
                        if(j+1<n){//可以往下走
                            int nk=k+(grid[i][j+1]=='('?1:-1);
                            if(nk>=0)//更新后的c值>=0 说明当前位置往后遍历可能得到有效的字符串
                                dp[i][j+1][nk]=true;
                        }
                    }
                }
            }
        }
        return dp[m-1][n-1][0];//最后一个格子的状态c=0如果满足 说明可以找到一个有效的字符串
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodePanda@GPF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值