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;
}
}