https://leetcode.com/contest/weekly-contest-74
井字棋,判断在下的过程中,会不会出现题目给的局面。
import java.util.Arrays;
/**
* Created by dezhonger on 2019/7/30
*/
public class Leetcode0794 {
public boolean validTicTacToe(String[] board) {
int a, b;
char c1, c2;
a = b = 0;
c1 = 'X';
c2 = 'O';
//分别表示两个人形成横着的,竖着的,斜对角三连个数
int[] gx = new int[3];
int[] go = new int[3];
for (String s : board) {
if (s.equals("XXX")) gx[0]++;
if (s.equals("OOO")) go[0]++;
for (char c : s.toCharArray()) {
if (c == c1) a++;
if (c == c2) b++;
}
}
if (b > a) return false;
if (a - b > 1) return false;
for (int i = 0; i < 3; i++) {
if (board[0].charAt(i) == c1 && board[1].charAt(i) == c1 && board[2].charAt(i) == c1) gx[1]++;
if (board[0].charAt(i) == c2 && board[1].charAt(i) == c2 && board[2].charAt(i) == c2) go[1]++;
}
if (board[0].charAt(0) == c1 && board[1].charAt(1) == c1 && board[2].charAt(2) == c1) gx[2]++;
if (board[0].charAt(0) == c2 && board[1].charAt(1) == c2 && board[2].charAt(2) == c2) go[2]++;
if (board[0].charAt(2) == c1 && board[1].charAt(1) == c1 && board[2].charAt(0) == c1) gx[2]++;
if (board[0].charAt(2) == c2 && board[1].charAt(1) == c2 && board[2].charAt(0) == c2) go[2]++;
//g1, g2分别表示两个人形成三连的个数
int g1, g2;
g1 = gx[0] + gx[1] + gx[2];
g2 = go[0] + go[1] + go[2];
//不可能俩人同时赢
if (g1 >= 1 && g2 >= 1) return false;
//不可能出现横着或竖着的有两个
if (gx[0] > 1 || gx[1] > 1) return false;
if (go[0] > 1 || go[1] > 1) return false;
//a赢的话,棋子个数必须必b多一个
if (g1 > 0 && a != b + 1) return false;
//b赢的话,旗子个数必须相等
if (g2 > 0 && a != b) return false;
return true;
}
}
2、Number of Matching Subsequences
判断一些字符串是不是原字符串的子序列
做法:dp的思想,先预处理出每个位置后a到z下一次出现的位置,然后用这个进行转移
class Solution {
//contest74
public int numMatchingSubseq(String S, String[] words) {
char[] s = S.toCharArray();
int[][] next = getNext(s);
int ret = 0;
for (String w : words) {
int pos = 0;
int add = 1;
for (char c : w.toCharArray()) {
pos = next[pos][c - 'a'];
if (pos > s.length) {
add = 0;
break;
}
}
ret += add;
}
return ret;
}
public int[][] getNext(char[] s) {
int n = s.length;
//next[i][j] 第i个字幕后字母j出现的位置, 1-base
int[][] next = new int[n + 1][26];
//第n个字母是结尾了,没有字母了
for (int i = 0; i < 26; i++) next[n][i] = n + 1;
for (int i = s.length - 1; i >= 0; i--) {
for (int j = 0; j < 26; j++) next[i][j] = next[i+1][j];
next[i][s[i] - 'a'] = i + 1;
}
return next;
}
}
3、Number of Subarrays with Bounded Maximum
求满足这样的子数组的个数,子数组的最大值在[L, R]之间
class Solution {
//计算最大值<=r的子数组的个数
private int f(int[] A, int r) {
int c = 0;
int res = 0;
for (int x : A) {
//c表示以x结尾的子数组个数,满足最大值<=r
if (x <= r) c++;
else c = 0;
res += c;
}
return res;
}
public int numSubarrayBoundedMax(int[] A, int L, int R) {
//最大值<=L的子数组,是最大值<=R的子数组的子集,相减就是最大值在[L, R]的子数组
return f(A, R) - f(A, L - 1);
}
}
4、Preimage Size of Factorial Zeroes Function
求阶乘最后0的个数是k的数字个数
注意到答案要么是0,要么是5,二分一下就可以了
public class Leetcode0793 {
public static void main(String[] args) {
new Leetcode0793().preimageSizeFZF(79);
}
//cal zeros of 5*x
int f(int x) {
int res = x;
while (x > 0) {
res += x / 5;
x /= 5;
}
return res;
}
public int preimageSizeFZF(int K) {
int r = K;
int l = 0;
while (l < r) {
int mid = (l + r) / 2;
int cnt = f(mid);
if (cnt == K) return 5;
if (cnt < K) l = mid + 1;
else r = mid - 1;
}
return f(l) == K ? 5 : 0;
}
}
本文提供了LeetCode周赛74的四道题目解答,包括井字棋状态验证、匹配子序列数量、限定最大值的子数组计数及阶乘尾零前驱数的计算。采用Java实现,涉及字符串处理、动态规划、数学分析和二分搜索等算法。

359

被折叠的 条评论
为什么被折叠?



