51. N皇后
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q'
和 '.'
分别代表了皇后和空位。
示例:
输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> sol;
vector<vector<int>> res;
vector<int> arr;
int end = n-1;
int start = 0;
for(int i = 0;i < n;++i)
arr.push_back(i);
Permutation(res, arr, start, end);
convertSol(res, sol);
return sol;
}
void convertSol(vector<vector<int>> &res, vector<vector<string>> &sol){
for(int i = 0;i < res.size();++i){
vector<string> vec;
for(int j = 0;j < res[i].size();++j){
int pos = res[i][j];
int k = 0;
string str;
while(k < pos){
str += ".";
++k;
}
str += "Q";
++k;
while(k < res[i].size()){
str += '.';
++k;
}
vec.push_back(str);
}
sol.push_back(vec);
}
}
void Permutation(vector<vector<int>> &res, vector<int> &arr, int start, int end){
if(start == end){
bool flag = true;
for(int i = 0;i < end;++i){
for(int j = 0;j <= end;++j){
if(i != j && (abs(arr[i] - arr[j]) == abs(i-j))){
flag = false;
break;
}//if
}//for
if(!flag)
break;
}//for
if(flag)
res.push_back(arr);
}
for(int i = start;i <= end;i++){
swap(arr[i], arr[start]);
Permutation(res, arr, start+1, end);
swap(arr[i], arr[start]);
}
}
};
52. N皇后 II
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回 n 皇后不同的解决方案的数量。
示例:
输入: 4
输出: 2
解释: 4 皇后问题存在如下两个不同的解法。
[
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
class Solution {
public:
int totalNQueens(int n) {
vector<vector<string>> sol;
vector<vector<int>> res;
vector<int> arr;
int end = n-1;
int start = 0;
for(int i = 0;i < n;++i)
arr.push_back(i);
Permutation(res, arr, start, end);
convertSol(res, sol);
return sol.size();
}
void convertSol(vector<vector<int>> &res, vector<vector<string>> &sol){
for(int i = 0;i < res.size();++i){
vector<string> vec;
for(int j = 0;j < res[i].size();++j){
int pos = res[i][j];
int k = 0;
string str;
while(k < pos){
str += ".";
++k;
}
str += "Q";
++k;
while(k < res[i].size()){
str += '.';
++k;
}
vec.push_back(str);
}
sol.push_back(vec);
}
}
void Permutation(vector<vector<int>> &res, vector<int> &arr, int start, int end){
if(start == end){
bool flag = true;
for(int i = 0;i < end;++i){
for(int j = 0;j <= end;++j){
if(i != j && (abs(arr[i] - arr[j]) == abs(i-j))){
flag = false;
break;
}//if
}//for
if(!flag)
break;
}//for
if(flag)
res.push_back(arr);
}
for(int i = start;i <= end;i++){
swap(arr[i], arr[start]);
Permutation(res, arr, start+1, end);
swap(arr[i], arr[start]);
}
}
};
53. 最大子序和
给定一个整数数组 nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if(nums.size() == 0) return 0;
return (max_sub(nums,0,nums.size()-1));
}
int max_sub(vector<int>& nums,int left,int right)
{
if(left == right)
return nums[left];
int center,left_sum,right_sum,s1=INT_MIN,s2=INT_MIN,l=0,r=0;
center = (left + right)/2;
left_sum=max_sub(nums,left,center);
right_sum=max_sub(nums,center+1,right);
for(int i = center;i>=left;i--)
{
l = l+nums[i];
if(s1<l) s1= l;
}
for(int i = center+1;i<=right;i++)
{
r = r+nums[i];
if(s2<r) s2= r;
}
if(left_sum > right_sum && left_sum > (s1+s2))
return left_sum;
else if(right_sum > (s1+s2))
return right_sum;
else return s1+s2;
}
};
54. 螺旋矩阵
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例 1:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
示例 2:
输入:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> res;
if(matrix.size()==0) return res;
int numi = matrix.size();
int numj = matrix[0].size();
int loop = numi>numj?(numj+1)/2:(numi+1)/2;
for(int i=0; i<loop; i++,numi-=2,numj-=2){
for(int col=i; col<i+numj; col++) res.push_back(matrix[i][col]);
for(int row=i+1; row<i+numi; row++) res.push_back(matrix[row][i+numj-1]);
if(numi==1 || numj==1) break;
for(int col=i+numj-2; col>=i; col--) res.push_back(matrix[i+numi-1][col]);
for(int row=i+numi-2; row>i; row--) res.push_back(matrix[row][i]);
}
return res;
}
};
55. 跳跃游戏
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 从位置 0 到 1 跳 1 步, 然后跳 3 步到达最后一个位置。
示例 2:
输入: [3,2,1,0,4]
输出: false
解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。
class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size();
int maxnum = 0;
for(int i=0; i<=n; i++){
if(i>maxnum) return false;
maxnum = max(maxnum, i+nums[i]);
if(maxnum >= n-1) return true;
}
}
};
(以上题目均摘自leetcode)