0
点赞
收藏
分享

微信扫一扫

day17-算法每日2题

624c95384278 2022-04-23 阅读 66
算法

678. 有效的括号字符串

class Solution {
     /**
     * 给定一个只包含三种字符的字符串:(,)和 *,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:
     * 任何左括号 (必须有相应的右括号 )。
     * 任何右括号 )必须有相应的左括号 (。
     * 左括号 ( 必须在对应的右括号之前 )。
     * 可以被视为单个右括号 ),或单个左括号 (,或一个空字符串。
     * 一个空字符串也被视为有效字符串。
     */
    public boolean checkValidString(String s) {
        if (s == null || s.length() == 0) return false;
        // 计算出左括号和有括号的个数  ll: 把左边多少个*转换成'(' rr: 把左边多少个*转换成')'
        int lCount = 0, rCount = 0, stars = 0, ll = 0, rr = 0;
        int len = s.length();
        char[] array = s.toCharArray();
        for (char c : array) {
            if (c == '(') lCount++;
            if (c == ')') rCount++;
            if (c == '*') stars++;
        }
        // 左括号比右括号数量少
        if (lCount < rCount) {
            ll = rCount - lCount;
            // '*'减少
            stars -= ll;
        }
        // 右括号比左括号数量少
        if (lCount > rCount) {
            rr = lCount - rCount;
            // '*'减少
            stars -= rr;
        }
        // '*'的个数不够
        if (stars < 0) return false;
        // 把剩下的'*'平分了
        ll += (stars >>> 1);
        rr += (stars >>> 1);
        // 从左边 填充'(' 
        for (int i = 0; i < len; i++) {
            if (ll == 0) break;
            if (array[i] == '*') {
                array[i] = '(';
                ll--;
                // '('数量++
                lCount++;
            }
        }
        // 从右边 填充')'
        for (int i = len - 1; i >= 0; i--) {
            if (rr == 0) break;
            if (array[i] == '*') {
                array[i] = ')';
                rr--;
                // '('数量++
                rCount++;
            }
        }
        // '(' 与 ')'数量不匹配
        if (lCount != rCount) return false;
        // 用来记录左括号的数量,如果是'('就+1,如果匹配一个')'就-1
        int cnt = 0;
        for (char c : array) {
            if (c == '(') cnt++;
            if (c == ')') cnt--;
            if (cnt < 0) return false;
        }
        return cnt == 0;
    }
}

204. 计数质数

class Solution {
     /**
     * 给定整数 n ,返回 所有小于非负整数 n 的质数的数量 。
     * 因为判断一个数字是否是素数的时间成本较高,所以我们不要一个个判断每个数字是否是素数,
     * 而是用排除法,把所有非素数都排除,剩下的就是素数。
     *
     * 判断当前的数,如果是质数了,它的倍数一定不是质数
     */
    public int countPrimes(int n) {
        boolean[] isPrime = new boolean[n];
        // 赋默认值
        Arrays.fill(isPrime, true);
        int cnt = 0;
        // 2 ~ sqrt(n)
        for (int i = 2; i < n; i++) {
            if (isPrime[i]) {
                for (int j = (i << 1); j < n; j += i) {
                    isPrime[j] = false;
                }
                cnt++;
            }
        }
        return cnt;
    }
}
举报

相关推荐

0 条评论