LeetCode Contest 74
2018-03-06 00:29
120 查看
日常鸽比赛,不过做完这周的题后感觉挺有意思的,记一下思路。
此时棋盘中只有
Valid Tic-Tac-Toe State
问题
给出一个井字棋的棋盘,求是否合理。思路
首先,井字棋先手为X,后手为
O,因此合理的棋盘中
X数量比
O数量多
1或两者相等,如果先手获胜,则
X数量必然比
O数量多
1;如果后手获胜,则
X数量必然和
O数量相等。其次,一旦有一方获胜,即任意一行或一列或对角线均为
X或均为
O,则游戏结束,因此棋盘不能同时满足双方的胜利条件。我一开始还想到一种情况,就是一方获胜后继续游戏,导致棋盘中只有一方胜利,这种情况满足前面的条件,但实际上不合理,所以要特别考虑。后来我发现要满足这种情况至少要有六个相同的符号:
XOO XXO XXX
此时棋盘中只有
X获胜,但事实上无论第六个
X放在哪个位置,前五个
X已经满足胜利条件了,因此这种情况是不合理的,如果仅根据胜利条件来判断棋盘是否合理会造成误判。不过,如果考虑
X和
O的数量关系就会得到正确的结果,因此不需要再当作特殊情况对待。
代码
class Solution { public: bool validTicTacToe(vector<string>& board) { int xCount = 0, oCount = 0; //X和O的数量 bool x3 = false, o3 = false; //X和O的胜利条件 for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { if (board[i][j] == 'X') ++xCount; else if (board[i][j] == 'O') ++oCount; } if (board[i][0] == 'X' && board[i][1] == 'X' && board[i][2] == 'X') x3 = true; if (board[0][i] == 'X' && board[1][i] == 'X' && board[2][i] == 'X') x3 = true; if (board[i][0] == 'O' && board[i][1] == 'O' && board[i][2] == 'O') o3 = true; if (board[0][i] == 'O' && board[1][i] == 'O' && board[2][i] == 'O') o3 = true; } if (board[0][0] == 'X' && board[1][1] == 'X' && board[2][2] == 'X') x3 = true; if (board[0][2] == 'X' && board[1][1] == 'X' && board[2][0] == 'X') x3 = true; if (board[0][0] == 'O' && board[1][1] == 'O' && board[2][2] == 'O') o3 = true; if (board[0][2] == 'O' && board[1][1] == 'O' && board[2][0] == 'O') o3 = true; if (o3 && x3) return false; //双方同时获胜 if (xCount > oCount + 1 || xCount < oCount) return false; //X和O数量关系不合理 else if (xCount == oCount + 1 && o3) return false; //X数量比O数量多1不可能后手获胜 else if (xCount == oCount && x3) return false; //X数量和O数量相等不可能先手获胜 return true; } };
Number of Matching Subsequences
问题
给出一个字符串和一组序列,求字符串的子序列数量。思路
求一个序列是否为字符串的子序列很简单,只需要遍历字符串就可以了,假设字符串长度n,序列长度
m,那么时间复杂度为
O(n),已经达到最优。但如果对每一个序列都遍历字符串,假设序列数为
l,那么时间复杂度为
O(l*n),这是最差的时间复杂度,很有可能超时。我一开始想用动态规划,记录字符串中每一个字母的下一个任意字母的最近位置,然后时间复杂度为
O(l*m),这是最优的时间复杂度,但空间复杂度为
O(26*n),不符合题目要求。后来我用
26个队列记录每个序列的匹配情况,只需要遍历一次字符串就可以判断子序列的数量了,时间复杂度为
O(l*m),具体步骤如下:
1.取每个序列第一个字母对应队列,记录当前序列以及当前位置并插入队列。 2.取字符串第一个字母对应队列,取出队列中所有元素视为匹配成功,记录对应每个序列的下一个位置并插入下一个字母的对应队列,即让每个匹配当前字母成功的序列等待下一次匹配。 3.遍历字符串所有字母,判断字符串的子序列数量。
代码
class Solution { public: int numMatchingSubseq(string S, vector<string>& words) { int ans = 0; vector<queue<pair<int, int>>> v(26); for (int i = 0; i < words.size(); ++i) { v[words[i][0]-'a'].push({i, 1}); } for (int i = 0; i < S.size(); ++i) { int s = v[S[i]-'a'].size(); for (int j = 0; j < s; ++j) { auto p = v[S[i]-'a'].front(); v[S[i]-'a'].pop(); if (p.second == words[p.first].size()) ++ans; else v[words[p.first][p.second]-'a'].push({p.first, p.second+1}); } } return ans; } };
Number of Subarrays with Bounded Maximum
问题
给出一个序列和上下界,求最大项在上下界之间的连续的子序列数量。思路
遍历序列,计算以每个元素结尾的符合要求的子序列数量并相加。如果当前元素大于上界,那么以当前元素结尾的子序列数量为0;如果当前元素在上下界之间,那么任意以当前元素结尾且不包含大于上界元素的子序列均符合要求,即从上一个大于上界元素的下一个元素开始到当前元素的数量;如果当前元素小于下界,那么任意以当前元素结尾且不包含大于上界元素且包含在上下界之间元素的子序列均符合要求,即从上一个大于上界元素的下一个元素开始到上一个在上下界之间元素的数量。
代码
class Solution { public: int numSubarrayBoundedMax(vector<int>& A, int L, int R) { int ans = 0; int a = 0; //以当前元素结尾且符合要求的子序列数量 int b = 0; //连续的小于下界元素的数量 for (int i = 0; i < A.size(); ++i) { if (A[i] > R) a = b = 0; else if (A[i] < L) ++b; else { a += b+1; b = 0; } ans += a; } return ans; } };
Preimage Size of Factorial Zeroes Function
问题
n!末尾的
0的数量为
K,求符合要求的
n的数量。
思路
n! = 1*2*3*···*n,因此
n!末尾的
0的数量与质因子
2和
5的数量有关。每有一个质因子
2和一个质因子
5,
n!末尾就会有一个
0,由于质因子
2的数量大于质因子
5的数量,所以
n!末尾的
0的数量等于质因子
5的数量。假设
m >= 0,那么
(5*m+1)!,(5*m+2)!,(5*m+3)!,(5*m+4)!,(5*m+5)!末尾的
0的数量相同,所以符合要求的
n的数量要么为
0,要么为
5。当
K = 1,2,3,4,6,···时
n的数量为
5,当
K = 5,···时
n的数量为
0,因为
n!的第
1个含质因子
5的因子为
5,第
2个因子为
10,第
3个因子为
15,第
4个因子为
20,第
5个因子为
25,由于
25有两个质因子
5,所以不存在
n!有且仅有
5个质因子
5。以此类推,不存在
n!有且仅有
30个质因子
5,因为第
25个因子为
125,
125有三个质因子
5。将
K作类似于进制的转换,我发现对于权
1,6,31,···,如果有任意一个的系数为
5,那么对应的
n!不存在。
代码
class Solution { public: int preimageSizeFZF(int K) { vector<int> v(15); v[0] = 1; for (int i = 1; i < 14; ++i) { v[i] = 5*v[i-1] + 1; //获得每一个权 } for (int i = 13; i >= 0; --i) { if (K / v[i] == 5) return 0; else K %= v[i]; } return 5; } };
总结
这次的题目非常有意思,我通过找规律得到了解题方法,但其中的原理并不能完全领会,还有待证明。相关文章推荐
- LeetCode Weekly Contest 74 793. Preimage Size of Factorial Zeroes Function【二分】
- leetCode练习(74)
- LeetCode Weekly Contest 52 Repeated String Match(string)
- LeetCode Weekly Contest 47解题思路
- LeetCode Weekly Contest 13-TotalHamming Distance【中】
- LeetCode Weekly Contest 23 之 539. Minimum Time Difference
- LeetCode 74 --- Search a 2D Matrix
- leetcode——74——Search a 2D Matrix
- LeetCode Weekly Contest 56 Find K-th Smallest Pair Distance
- leetcode contest两题
- [LeetCode] Output Contest Matches 输出比赛匹配对
- [Leetcode 74, medium] Search a 2D Matrix
- 【leetcode】Array——Search a 2D Matrix(74)
- LeetCode Weekly Contest 40解题思路
- LeetCode Weekly Contest 41解题思路
- LeetCode Weekly Contest 26解题思路
- 74_leetcode_Convert Sorted Array to Binary Search Tree
- Leetcode 74 Search a 2D Matrix
- LeetCode Weekly Contest 36解题思路
- LeetCode Weekly Contest 13-Matchsticks to Square【中】