算法学习——LeetCode力扣补充篇5
52. N 皇后 II
52. N 皇后 II - 力扣(LeetCode)
描述
n 皇后问题 研究的是如何将 n 个皇后放置在 n × n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回 n 皇后问题 不同的解决方案的数量。
示例
示例 1:
输入:n = 4
输出:2
解释:如上图所示,4 皇后问题存在两个不同的解法。
示例 2:
输入:n = 1
输出:1
提示
1 <= n <= 9
代码解析
class Solution {
public:
int result = 0;
vector<pair<int , int>> path;
void track_back(int n , int deep )
{
if(deep > n) return;
if(deep == n) result++;
for(int i=0 ; i<n ;i++)
{
pair<int,int> tmp(deep,i);
bool flag = true;
for(auto it:path)
{
if( deep == it.first || i == it.second
|| abs(deep - it.first) == abs(i - it.second) )
{
flag = false;
break;
}
}
if(flag == true)
{
path.push_back(tmp);
track_back(n,deep+1);
path.pop_back();
}
}
return;
}
int totalNQueens(int n) {
track_back(n,0);
return result;
}
};
649. Dota2 参议院
649. Dota2 参议院 - 力扣(LeetCode)
描述
Dota2 的世界里有两个阵营:Radiant(天辉)和 Dire(夜魇)
Dota2 参议院由来自两派的参议员组成。现在参议院希望对一个 Dota2 游戏里的改变作出决定。他们以一个基于轮为过程的投票进行。在每一轮中,每一位参议员都可以行使两项权利中的 一 项:
禁止一名参议员的权利:参议员可以让另一位参议员在这一轮和随后的几轮中丧失 所有的权利 。
宣布胜利:如果参议员发现有权利投票的参议员都是 同一个阵营的 ,他可以宣布胜利并决定在游戏中的有关变化。
给你一个字符串 senate 代表每个参议员的阵营。字母 ‘R’ 和 'D’分别代表了 Radiant(天辉)和 Dire(夜魇)。然后,如果有 n 个参议员,给定字符串的大小将是 n。
以轮为基础的过程从给定顺序的第一个参议员开始到最后一个参议员结束。这一过程将持续到投票结束。所有失去权利的参议员将在过程中被跳过。
假设每一位参议员都足够聪明,会为自己的政党做出最好的策略,你需要预测哪一方最终会宣布胜利并在 Dota2 游戏中决定改变。输出应该是 “Radiant” 或 “Dire” 。
示例
示例 1:
输入:senate = “RD”
输出:“Radiant”
解释:
第 1 轮时,第一个参议员来自 Radiant 阵营,他可以使用第一项权利让第二个参议员失去所有权利。
这一轮中,第二个参议员将会被跳过,因为他的权利被禁止了。
第 2 轮时,第一个参议员可以宣布胜利,因为他是唯一一个有投票权的人。
示例 2:
输入:senate = “RDD”
输出:“Dire”
解释:
第 1 轮时,第一个来自 Radiant 阵营的参议员可以使用第一项权利禁止第二个参议员的权利。
这一轮中,第二个来自 Dire 阵营的参议员会将被跳过,因为他的权利被禁止了。
这一轮中,第三个来自 Dire 阵营的参议员可以使用他的第一项权利禁止第一个参议员的权利。
因此在第二轮只剩下第三个参议员拥有投票的权利,于是他可以宣布胜利
代码解析
class Solution {
public:
string predictPartyVictory(string senate) {
queue<int> my_que_D;
queue<int> my_que_R;
for(int i=0 ; i<senate.size() ;i++)
{
if(senate[i] == 'R') my_que_R.push(i);
if(senate[i] == 'D') my_que_D.push(i);
}
for(int i=0 ; i<senate.size() ;i++)
{
if(my_que_R.size() !=0 && my_que_D.size()!=0)
{
// cout<<i<<' '<<my_que_R.front()<<' '<<my_que_D.front()<<endl;
if(my_que_R.front() == i )
{
my_que_D.pop();
my_que_R.push(my_que_R.front());
my_que_R.pop();
}
if(my_que_D.front() == i )
{
my_que_R.pop();
my_que_D.push(my_que_D.front());
my_que_D.pop();
}
}else break;
if(i==senate.size()-1 && my_que_R.size() !=0 && my_que_D.size()!=0 ) i=-1;
}
// cout<<my_que_R.front()<<' '<<my_que_D.front();
if(my_que_R.size() !=0 && my_que_D.size()==0 ) return "Radiant";
else return "Dire";
}
};
1221. 分割平衡字符串
1221. 分割平衡字符串 - 力扣(LeetCode)
描述
平衡字符串 中,‘L’ 和 ‘R’ 字符的数量是相同的。
给你一个平衡字符串 s,请你将它分割成尽可能多的子字符串,并满足:
每个子字符串都是平衡字符串。
返回可以通过分割得到的平衡字符串的 最大数量 。
示例
示例 1:
输入:s = “RLRRLLRLRL”
输出:4
解释:s 可以分割为 “RL”、“RRLL”、“RL”、“RL” ,每个子字符串中都包含相同数量的 ‘L’ 和 ‘R’ 。
示例 2:
输入:s = “RLRRRLLRLL”
输出:2
解释:s 可以分割为 “RL”、“RRRLLRLL”,每个子字符串中都包含相同数量的 ‘L’ 和 ‘R’ 。
注意,s 无法分割为 “RL”、“RR”、“RL”、“LR”、“LL” 因为第 2 个和第 5 个子字符串不是平衡字符串。
示例 3:
输入:s = “LLLLRRRR”
输出:1
解释:s 只能保持原样 “LLLLRRRR” 。
提示
2 <= s.length <= 1000
s[i] = ‘L’ 或 ‘R’
s 是一个 平衡 字符串
代码解析
class Solution {
public:
int balancedStringSplit(string s) {
int result = 0;
int R_num = 0 , L_num = 0;
for(int i=0 ; i<s.size() ;i++)
{
if(s[i] == 'R') R_num++;
else if(s[i] == 'L') L_num++;
if(R_num == L_num )
{
result++;
R_num = 0;
L_num = 0;
}
}
return result;
}
};
5. 最长回文子串
5. 最长回文子串 - 力扣(LeetCode)
描述
给你一个字符串 s,找到 s 中最长的回文
子串
。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
示例
示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:“bb”
提示
1 <= s.length <= 1000
s 仅由数字和英文字母组成
代码解析
暴力法
class Solution {
public:
bool cheak(string &s , int left ,int right)
{
for(int i = left , j = right ; i<j ; i++ , j--)
{
if(s[i] != s[j]) return false;
}
return true;
}
string longestPalindrome(string s) {
if(s.size() <= 1) return s;
int string_max = 0;
string result;
for(int i=0 ; i<s.size() ;i++)
{
for(int j=i ; j<s.size() ;j++)
{
if(s[j] == s[i] && cheak(s,i,j) == true && (j-i+1) > string_max)
{
// cout<<i<<' '<<j<<endl;
string_max = j-i+1;
result.assign(s.begin()+i , s.begin()+j+1);
}
}
}
return result;
}
};
动态规划
class Solution {
public:
string longestPalindrome(string s) {
if(s.size() <= 1) return s;
vector<vector<bool>> dp(s.size() , vector<bool>(s.size() , false));
int left = 0 , right = 0;
for(int i=s.size()-1 ; i>=0 ; i--)
{
for(int j=i ; j<s.size() ;j++)
{
if(s[i] == s[j] && (j-i<=1 ||dp[i+1][j-1] == true) )
{
dp[i][j] = true;
if( j-i > right -left)
{
left = i;
right = j;
}
}
}
}
string result(s.begin()+left , s.begin()+right+1);
return result;
}
};