1、N-Queens I&&II
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
Given an integer n, return all distinct solutions to the n-queens puzzle.
Each solution contains a distinct board configuration of the n-queens' placement, where 'Q'
and '.'
both indicate a queen and an empty space respectively.
For example,
There exist two distinct solutions to the 4-queens puzzle:
[ [".Q..", // Solution 1 "...Q", "Q...", "..Q."], ["..Q.", // Solution 2 "Q...", "...Q", ".Q.."] ]回溯法,将所有结果输出
class Solution {
public:
vector<vector<string> > res;
//vector<vector<string>> res;
void helper(vector<string> &cur, int row)
{
if(row == cur.size())
{
res.push_back(cur);
return;
}
for(int col = 0; col < cur.size(); col++)
if(isValid(cur, row, col))
{
cur[row][col] = 'Q';
helper(cur, row+1);
cur[row][col] = '.';
}
}
//判断在cur[row][col]位置放一个皇后,是否是合法的状态
//已经保证了每行一个皇后,只需要判断列是否合法以及对角线是否合法。
bool isValid(vector<string> &cur, int row, int col)
{
//列
for(int i = 0; i < row; i++)
if(cur[i][col] == 'Q')return false;
//左对角线(只需要判断对角线上半部分,因为后面的行还没有开始放置)
for(int i = row-1, j=col-1; i >= 0 && j >= 0; i--,j--)
if(cur[i][j] == 'Q')return false;
//右对角线(只需要判断对角线上半部分,因为后面的行还没有开始放置)
for(int i = row-1, j=col+1; i >= 0 && j < cur.size(); i--,j++)
if(cur[i][j] == 'Q')return false;
return true;
}
vector<vector<string> > solveNQueens(int n) {
vector<string> ret(n, string(n,'.'));
//helper(ret, 0);
dfs(ret,0);
return res;
}
bool isvalid(vector<string> &cur,int row,int col){
for(int i = 0;i<row;i++){
if(cur[i][col]=='Q'){
return false;
}
}
for(int i = row-1,j = col-1;i>=0&&j>=0;i--,j--){
if(cur[i][j]=='Q'){
return false;
}
}
for(int i=row-1,j = col+1;i>=0&&j<cur.size();i--,j++){
if(cur[i][j]=='Q'){
return false;
}
}
return true;
}
void dfs(vector<string> &cur,int row){
if(row == cur.size()){
res.push_back(cur);
return;
}
for(int col = 0;col<cur.size();col++){
if(isvalid(cur,row,col)){
cur[row][col]='Q';
dfs(cur,row+1);
cur[row][col] = '.';
}
}
}
};
class Solution {
public:
vector<vector<string> > res;
//vector<vector<string>> res;
void helper(vector<string> &cur, int row)
{
if(row == cur.size())
{
res.push_back(cur);
return;
}
for(int col = 0; col < cur.size(); col++)
if(isValid(cur, row, col))
{
cur[row][col] = 'Q';
helper(cur, row+1);
cur[row][col] = '.';
}
}
//判断在cur[row][col]位置放一个皇后,是否是合法的状态
//已经保证了每行一个皇后,只需要判断列是否合法以及对角线是否合法。
bool isValid(vector<string> &cur, int row, int col)
{
//列
for(int i = 0; i < row; i++)
if(cur[i][col] == 'Q')return false;
//左对角线(只需要判断对角线上半部分,因为后面的行还没有开始放置)
for(int i = row-1, j=col-1; i >= 0 && j >= 0; i--,j--)
if(cur[i][j] == 'Q')return false;
//右对角线(只需要判断对角线上半部分,因为后面的行还没有开始放置)
for(int i = row-1, j=col+1; i >= 0 && j < cur.size(); i--,j++)
if(cur[i][j] == 'Q')return false;
return true;
}
vector<vector<string> > solveNQueens(int n) {
vector<string> ret(n, string(n,'.'));
//helper(ret, 0);
dfs(ret,0);
return res;
}
bool isvalid(vector<string> &cur,int row,int col){
for(int i = 0;i<row;i++){
if(cur[i][col]=='Q'){
return false;
}
}
for(int i = row-1,j = col-1;i>=0&&j>=0;i--,j--){
if(cur[i][j]=='Q'){
return false;
}
}
for(int i=row-1,j = col+1;i>=0&&j<cur.size();i--,j++){
if(cur[i][j]=='Q'){
return false;
}
}
return true;
}
void dfs(vector<string> &cur,int row){
if(row == cur.size()){
res.push_back(cur);
return;
}
for(int col = 0;col<cur.size();col++){
if(isvalid(cur,row,col)){
cur[row][col]='Q';
dfs(cur,row+1);
cur[row][col] = '.';
}
}
}
};
Follow up for N-Queens problem.
Now, instead outputting board configurations, return the total number of distinct solutions.
原理相似,count++
class Solution {
public:
int value;
int totalNQueens(int n) {
value = 0;
vector<string> ret(n, string(n,'.'));
dfs(ret,0);
return value;
}
bool isvalid(vector<string> &cur,int row,int col){
for(int i = 0;i<row;i++){
if(cur[i][col]=='Q'){
return false;
}
}
for(int i = row-1,j = col-1;i>=0&&j>=0;i--,j--){
if(cur[i][j]=='Q'){
return false;
}
}
for(int i=row-1,j = col+1;i>=0&&j<cur.size();i--,j++){
if(cur[i][j]=='Q'){
return false;
}
}
return true;
}
void dfs(vector<string> &cur,int row){
if(row == cur.size()){
value++;
return;
}
for(int col = 0;col<cur.size();col++){
if(isvalid(cur,row,col)){
cur[row][col]='Q';
dfs(cur,row+1);
cur[row][col] = '.';
}
}
}
};
2、Length of Last Word
Given a string s consists of upper/lower-case alphabets and empty space characters ' '
, return the length of last word in the string.
If the last word does not exist, return 0.
Note: A word is defined as a character sequence consists of non-space characters only.
For example,
Given s = "Hello World"
,
return 5
.
int lengthOfLastWord(const char *s) {
string str = s;
int len = str.size();
if(len==0){
return 0;
}
int wlen = 0;
len--;
while(len>=0&&str[len]==' '){
len--;
}
while(len>=0&&str[len]!=' '){
wlen++;
len--;
}
return wlen;
}
3、Maximum Subarray
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array [−2,1,−3,4,−1,2,1,−5,4]
,
the contiguous subarray [4,−1,2,1]
has the largest sum = 6
.
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
int maxSubArray(int A[], int n) {
int sum = A[0], max = A[0];
for (int i = 1; i < n; i++) {
sum = sum < 0 ? A[i] : sum + A[i];
max = sum > max ? sum : max;
}
return max;
}
int maxSubArray(int A[], int n) {
int sum = A[0], max = A[0];
for (int i = 1; i < n; i++) {
sum = sum < 0 ? A[i] : sum + A[i];
max = sum > max ? sum : max;
}
return max;
}
4、Jump Game
Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Determine if you are able to reach the last index.
For example:
A = [2,3,1,1,4]
, return true
.
A = [3,2,1,0,4]
, return false
.
class Solution {
public:
/*
第二种方案,增加一个从0位置所能到的最远距离 maxdis
如果0可到达当前位置,而且当前位置可以到达n-1,返回true
如果0不可到达当前位置,而且当前位置不能到达n-1,返回false
其他情况几率maxdis
*/
bool canJump(int A[], int n) {
if(n==0||A==NULL){
return false;
}
if(A[0]>=n-1){
return true;
}
int maxdis = A[0];
if(maxdis==0){
return false;
}
for(int i = 1;i<n-1;i++){
if(maxdis>=i&&A[i]+i>=n-1){
return true;
}
if(maxdis<=i&&A[i]==0){
return false;
}
if(i+A[i]>maxdis){
maxdis = i+A[i];
}
}
return false;
}
};
class Solution {
public:
/*
第二种方案,增加一个从0位置所能到的最远距离 maxdis
如果0可到达当前位置,而且当前位置可以到达n-1,返回true
如果0不可到达当前位置,而且当前位置不能到达n-1,返回false
其他情况几率maxdis
*/
bool canJump(int A[], int n) {
if(n==0||A==NULL){
return false;
}
if(A[0]>=n-1){
return true;
}
int maxdis = A[0];
if(maxdis==0){
return false;
}
for(int i = 1;i<n-1;i++){
if(maxdis>=i&&A[i]+i>=n-1){
return true;
}
if(maxdis<=i&&A[i]==0){
return false;
}
if(i+A[i]>maxdis){
maxdis = i+A[i];
}
}
return false;
}
};
5、Merge Intervals &&
Insert Interval
Given a collection of intervals, merge all overlapping intervals.
For example,
Given [1,3],[2,6],[8,10],[15,18]
,
return [1,6],[8,10],[15,18]
.
/**
* Definition for an interval.
* struct Interval {
* int start;
* int end;
* Interval() : start(0), end(0) {}
* Interval(int s, int e) : start(s), end(e) {}
* };
*/
class Solution {
public:
/*
这个很赞
先排序
然后合并,合并的时候通过对另外构造一个vector,然后判断如果start在上一个区间中间,则这个区间重新定义长度
*/
static bool comp(Interval a, Interval b)
{
return a.start < b.start;
}
vector<Interval> merge(vector<Interval> &intervals) {
if(intervals.empty())return intervals;
sort(intervals.begin(), intervals.end(), comp);
vector<Interval> res;
res.push_back(intervals[0]);
for(int i = 1; i < intervals.size(); i++)
{
Interval &p = res.back();
if(intervals[i].start > p.end)res.push_back(intervals[i]);
else if(intervals[i].end > p.end)p.end = intervals[i].end;
}
return res;
}
};
这个和上一个是一个类型的题目。
/**
* Definition for an interval.
* struct Interval {
* int start;
* int end;
* Interval() : start(0), end(0) {}
* Interval(int s, int e) : start(s), end(e) {}
* };
*/
class Solution {
public:
/*
这个很赞
先排序
然后合并,合并的时候通过对另外构造一个vector,然后判断如果start在上一个区间中间,则这个区间重新定义长度
*/
static bool comp(Interval a, Interval b)
{
return a.start < b.start;
}
vector<Interval> merge(vector<Interval> &intervals) {
if(intervals.empty())return intervals;
sort(intervals.begin(), intervals.end(), comp);
vector<Interval> res;
res.push_back(intervals[0]);
for(int i = 1; i < intervals.size(); i++)
{
Interval &p = res.back();
if(intervals[i].start > p.end)res.push_back(intervals[i]);
else if(intervals[i].end > p.end)p.end = intervals[i].end;
}
return res;
}
};
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).
You may assume that the intervals were initially sorted according to their start times.
Example 1:
Given intervals [1,3],[6,9]
, insert and merge [2,5]
in as [1,5],[6,9]
.
Example 2:
Given [1,2],[3,5],[6,7],[8,10],[12,16]
, insert and merge [4,9]
in as [1,2],[3,10],[12,16]
.
This is because the new interval [4,9]
overlaps with [3,5],[6,7],[8,10]
.
这两个题目都好赞,根据比较start和end来插入数据。
class Solution {
public:
vector<Interval> insert(vector<Interval> &intervals, Interval newInterval) {
vector<Interval> ret;
int sta = newInterval.start;
int end = newInterval.end;
int i = 0;
for(;i<intervals.size()&&sta>intervals[i].end;i++){
ret.push_back(intervals[i]);
}
if(i<intervals.size()){
sta = min(sta,intervals[i].start);
}
for (; i<intervals.size() && end >= intervals[i].start; i++)
end = max(end, intervals[i].end);
ret.push_back(Interval(sta, end));
ret.insert(ret.end(), intervals.begin()+i, intervals.end());
return ret;
}
};
6、Rotate ImageYou are given an n x n 2D matrix representing an image.
Rotate the image by 90 degrees (clockwise).
Follow up:
Could you do this in-place?
方法二,这个是一个数学原理方案,原理主要是先左上角和右下角进行对折互换,然后再沿中线进行对折兑换,就可以了。
class Solution {
public:
/*先延对角线翻转,然后中线翻转
http://fisherlei.blogspot.sg/2013/01/leetcode-rotate-image.html
*/
void rotate(vector<vector<int> > &matrix) {
int n = matrix.size();
if(n<=1){
return;
}
for(int i = 0;i<n;i++){
for(int j = 0;j<n-i;j++){
swap(matrix[i][j],matrix[n-1-j][n-1-i]);
}
}
for(int i = 0;i<n/2;i++){
for(int j = 0;j<n;j++){
swap(matrix[i][j],matrix[n-1-i][j]);
}
}
}
};
class Solution {
public:
/*先延对角线翻转,然后中线翻转
http://fisherlei.blogspot.sg/2013/01/leetcode-rotate-image.html
*/
void rotate(vector<vector<int> > &matrix) {
int n = matrix.size();
if(n<=1){
return;
}
for(int i = 0;i<n;i++){
for(int j = 0;j<n-i;j++){
swap(matrix[i][j],matrix[n-1-j][n-1-i]);
}
}
for(int i = 0;i<n/2;i++){
for(int j = 0;j<n;j++){
swap(matrix[i][j],matrix[n-1-i][j]);
}
}
}
};
7、Anagrams
Given an array of strings, return all groups of strings that are anagrams.
Note: All inputs will be in lower-case.
For example:
Input: ["tea","and","ate","eat","den"]
Output: ["tea","ate","eat"]
原理:读入一个string,然后排序,将排序好的string 添加如map然后读入下一个string,同样排序,如果存在,则添加如vector里面。
vector<string> anagrams(vector<string> &strs) {
vector<string> ret;
if(strs.size()<=1){
return ret;
}
map<string,int> vec;
for(int i=0;i<strs.size();i++){
string s = strs[i];
sort(s.begin(),s.end());
if(vec.find(s)==vec.end()){
vec.insert(make_pair(s, i));
}
else{
if(vec[s]>=0){
ret.push_back(strs[vec[s]]);
vec[s]=-1;
}
ret.push_back(strs[i]);
}
}
}
8、First Missing Positive
vector<string> anagrams(vector<string> &strs) {
vector<string> ret;
if(strs.size()<=1){
return ret;
}
map<string,int> vec;
for(int i=0;i<strs.size();i++){
string s = strs[i];
sort(s.begin(),s.end());
if(vec.find(s)==vec.end()){
vec.insert(make_pair(s, i));
}
else{
if(vec[s]>=0){
ret.push_back(strs[vec[s]]);
vec[s]=-1;
}
ret.push_back(strs[i]);
}
}
}
Given an unsorted integer array, find the first missing positive integer.
For example,
Given [1,2,0]
return 3
,
and [3,4,-1,1]
return 2
.
Your algorithm should run in O(n) time and uses constant space.
这个题目,理解提议很重要,题目要求找到第一个丢失的正数。所以可以排除掉所有的负数。class Solution {
public:
/*
注意几个特别的字眼,正整数,所以其他的不用管,连续的正整数在哪里断开了,是问题关键,将正整数存入其数值所代表的位置
*/
int firstMissingPositive(int A[], int n) {
int i = 0;
for(;i<n;){
if(A[i]<=0||A[i]==i+1||A[i]>n||A[i]==A[A[i]-1]){
i++;
}
else{
swap(A[i],A[A[i]-1]);
}
}
for(i = 0;i<n;i++){
if(i+1!=A[i]){
break;
}
}
return i+1;
}
};
9、Trapping Rain Water
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
For example,
Given [0,1,0,2,1,0,1,3,2,1,2,1]
, return 6
.
The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!
原理是,从左到右,从右到左,分别计算当前bar的左边和右边最大值,这样就可以计算出当前bar可以存储多少水量。class Solution {
public:
int trap(int A[], int n) {
//no way to contain any water
if(n <= 2) return 0;
//1. first run to calculate the heiest bar on the left of each bar
int *lmh = new int[n];//for the most height on the left
lmh[0] = 0;
int maxh = A[0];
for(int i = 1; i < n; ++i) {
lmh[i] = maxh;
if(maxh < A[i]) maxh = A[i];
}
int trapped = 0;
//2. second run from right to left,
// caculate the highest bar on the right of each bar
// and calculate the trapped water simutaniously
maxh = A[n-1];
for(int i = n - 2; i > 0; --i) {
int left = lmh[i];
int right = maxh;
int container = min(left,right);
if(container > A[i]) {
trapped += container - A[i];
}
if(maxh < A[i]) maxh = A[i];
}
delete lmh;
return trapped;
}
};
10、Multiply Strings
Given two numbers represented as strings, return multiplication of the numbers as a string.
Note: The numbers can be arbitrarily large and are non-negative.
字符串的相乘,本科的时候有一次实验是做大整数相乘int data[100000];
string multiply(string num1, string num2) {
reverse(num1.begin(),num1.end());
reverse(num2.begin(),num2.end());
memset(data,0,sizeof(data));
int len1 = num1.size();
int len2 = num2.size();
for(int i = 0;i<len1;i++){
for(int j = 0;j<len2;j++){
data[i+j] += (num1[i]-'0')*(num2[j]-'0');
}
}
int p,temp;
p = 0;
int i = 0;
while(i<len1+len2||p!=0){
temp = data[i]+p;
data[i] = temp%10;
p = temp/10;
i++;
}
string result;
bool flag = 0;
for(;i>=0;i--){
if(flag == 0&&data[i]==0){
continue;
}
else{
flag = 1;
result += (char)(data[i]+'0');
}
}
if(flag == 0){
return "0";
}
else{
return result;
}
}