Thursday, October 24, 2013
警示!!!!!!!!!
NOTE:
title里加了 !!!!!!!!的是Tiger没有自己搞定的题目。 要多多注意
wordLadderII 虽然自己的思路是对的。但是,由于特别容易犯错, 也加了警示。
56. Merge Intervals ------- M !!!!!
Input: [[1,3],[2,6],[8,10],[15,18]] Output: [[1,6],[8,10],[15,18]] Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].
Input: [[1,4],[4,5]] Output: [[1,5]] Explanation: Intervals [1,4] and [4,5] are considered overlapping.
A:
自己写了Comparator里的compare函数。class Solution {public:vector<vector<int>> merge(vector<vector<int>>& intervals) {sort(intervals.begin(), intervals.end(),[](vector<int>& a, vector<int>& b) {return a[0] == b[0] ? a[1] < b[1] : a[0] < b[0];});vector<vector<int>> res;for (auto& interval : intervals) {if (res.empty() || res.back()[1] < interval[0]) {res.push_back(interval);} else {res.back()[1] = max(interval[1], res.back()[1]);}}return res;}};
Learned:
1: Collections framework 的用法。 Tuitoral
Wednesday, October 23, 2013
59. Spiral Matrix II ----M
A:Given a positive integer n, generate a square matrix filled with elements from 1 to n2 in spiral order.
Example:
Input: 3 Output: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
同问题一。 仍然是一层层地剥开设置。 复杂度为n2
class Solution { public: vector<vector<int>> generateMatrix(int n) { vector<vector<int>> V(n, vector<int>(n,0)); int c = 0; for(int layer = 0; layer < (n+1)/2;layer++){ int x0 = layer, y0 = x0, x1 = n-layer-1, y1 = x1; for(int col = y0;col<=y1; col++){ // NEED <= in case x0 == x1 V[x0][col] = ++c; } for(int row = x0+1; row<=x1;row++){ V[row][y1] = ++c; } if(x1>x0){ for(int col = y1-1;col>= y0;col--){ V[x1][col] = ++c; } } if(y0<y1){ for(int row = x1-1; row > x0;row--){ V[row][y0] = ++c; } } } return V; } };上面的是对于 m * n 矩阵的。 而对于 n * n 矩阵, 左右判断的可以省略掉 (当x0==x1时,只会增加第一个for loop)
class Solution { public: vector<vector<int>> generateMatrix(int n) { vector<vector<int>> V(n, vector<int>(n,0)); int c = 0; for(int layer = 0; layer < (n+1)/2;layer++){ int x0 = layer, y0 = x0, x1 = n-layer-1, y1 = x1; for(int col = y0;col<=y1; col++){ // NEED <= in case x0 == x1 V[x0][col] = ++c; } for(int row = x0+1; row<=x1;row++){ V[row][y1] = ++c; } for(int col = y1-1;col>= y0;col--){ V[x1][col] = ++c; } for(int row = x1-1; row > x0;row--){ V[row][y0] = ++c; } } return V; } };
Mistakes:
-------------------------------------3 rd Pass -----------------------------------
当n 是奇数,判断中心点的时候, 一开始写成了 if(n%2 == 1 && layer +1 = n/2) 这样当n ==1的时候是不对的。
public class Solution { public int[][] generateMatrix(int n) { int[][] A = new int[n][n]; helper(A,0,n-1,1); return A; } private void helper(int[][] A , int l, int r, int k){// l is the top left, r is down right corner if(l>r) return; if(l==r){ A[l][l] = k++; return; } for(int j=l;j<r;j++) A[l][j]=k++; for(int i = l;i<r;i++) A[i][r] = k++; for(int j = r;j> l; j--) A[r][j] = k++; for(int i = r;i>l;i--) A[i][l] = k++; helper(A,l+1,r-1, k); } }
Learned:
54. Spiral Matrix --- M
Given an m x n
matrix
, return all elements of the matrix
in spiral order.
Example 1:

Input: matrix = [[1,2,3],[4,5,6],[7,8,9]] Output: [1,2,3,6,9,8,7,4,5]
Example 2:

Input: matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]] Output: [1,2,3,4,8,12,11,10,9,5,6,7]
Constraints:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100
A:
一层层地剥开罢, 按照上->右->下->左的顺序加入即可。注意,当只有一行,一列的情况。(某一行,或某一列尽量取多的值。 同时, 在检查下面行,左边列的时候,要检查是否本行/列 已经加过。
class Solution {public:vector<int> spiralOrder(vector<vector<int>>& matrix) {vector<int> res;int m = matrix.size(), n = matrix[0].size();int layer = 0; // layer starting from 0,while (layer <= m - 1 - layer && layer <= n - 1 - layer) {int r0 = layer, c0 = layer;int r1 = layer, c1 = n - 1 - layer;int r2 = m - 1 - layer, c2 = n - 1 - layer;int r3 = m - 1 - layer, c3 = layer;// top row, (gready first)for (int j = c0; j <= c1; j++) {res.push_back(matrix[r0][j]);}// right columnfor (int i = r1+1; i <= r2; i++) {res.push_back(matrix[i][c1]);}// bottom rowif (r2 > r0) {for (int j = c2 - 1; j >= c3; j--) {res.push_back(matrix[r2][j]);}}// left columnif (c3 < c2) {for (int i = r3 - 1; i > r0; i--) {res.push_back(matrix[i][c3]);}}layer++;}return res;}};
Mistakes:
1: 由于我们每个边都是取了开头,没有取最后一个。 导致,当只有一个点的时候,我们没能取出来。
解决方法: 把upper row,全部取出来。
2; 当只有一行的时候, 我们取了两遍, 而这里,我们应该是先比较行数和列数,是否相同的。
3: 当只有一列的时候, 类似于第一个错误,我们应该在某一列, 尽量取多的值。
i. e. right col 第一个不取,但是取最后一个。
55. Jump Game -M
Given an array of non-negative integers, you are initially positioned at the first index of the array.
Input: [2,3,1,1,4] Output: true Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.
Input: [3,2,1,0,4] Output: false Explanation: You will always arrive at index 3 no matter what. Its maximum jump length is 0, which makes it impossible to reach the last index.
A:
----------跟第二遍的思路一样---------------思想:每次jump到最远的位置,然后,每一个可以jump的位置,都得visit看其是否更新reached 的值
class Solution { public: bool canJump(vector<int>& nums) { int n = nums.size(); int far = 0; for(int i =0;i<=far && far < n;++i) { far = max(far, i + nums[i]); } return far>=n-1; } };
-------------1 st pass-----------------------------
从0开始,每一个位置都做标记,查看是否可以达到最后的点。
class Solution { public: bool canJump(vector<int>& nums) { int n = nums.size(); // mark as negative if can arrive if(n<=1) return true; nums[0] *= -1; for(int i =0;i<n;++i) { int v = nums[i]; if(v>0) break; for(int j = i+1;j<=i-v && j<n ; ++j) { if(j==n-1) // hit now, since nums[n-1] can be 0, we need check here return true; if(nums[j]>0) nums[j] *= -1; } } return false; } };
Mistakes:
1; 第二遍的时候, 忘记了判断curFarest是否很大。 如果超过边境的话, 会导致A[i] 出现 out of boundary exception.
2:
Learned:
---------------------------第三遍-------------
Error:
1: for loop 中, 应该是 <= rightMost的,就是说,要计算新的最远端的距离的时候,要包括原本最远可以到达的点。
public class Solution { public boolean canJump(int[] A) { if(A.length <= 1) return true; int lastRightMost = 0; int rightMost = A[0]; while(rightMost>lastRightMost && rightMost<A.length-1){ int newRightMost = rightMost; for(int i = lastRightMost+1;i<=rightMost;i++){ int newRightEnd = i+A[i]; newRightMost = Math.max(newRightMost,newRightEnd); } lastRightMost = rightMost; if(newRightMost > rightMost){ rightMost = newRightMost; } } return rightMost>=A.length-1; } }
52. N-Queens II ---H !!!!!!!!!!!!!!!!!!!!!!!!!!
The n-queens puzzle is the problem of placing n
queens on an n x n
chessboard such that no two queens attack each other.
Given an integer n
, return the number of distinct solutions to the n-queens puzzle.
Example 1:

Input: n = 4 Output: 2 Explanation: There are two distinct solutions to the 4-queens puzzle as shown.
Example 2:
Input: n = 1 Output: 1
Constraints:
1 <= n <= 9
仅仅地把问题一,改改,拿过来,(用DFS )来做,会慢。(但是能过)
下面的代码,不是自己写的,是网上copy别人的。
第一次, 让爷们儿,放弃了自己的方式。
好好学着下面的代码!!!!!!!!!!!!(time beat 100%; memory beat 96%)
class Solution {public:int totalNQueens(int n) {vector<int> pattern(n); //pattern[i] store the column index of the queen in row ireturn countSolution(1, pattern);}private:int countSolution(int k, vector<int>& pattern) { //k: the current row numberint n = pattern.size();int res = 0;for (int i = 0; i < n; i++) {bool valid = true;for (int j = 0; j < k - 1; j++) {if (pattern[j] == i || abs(j - k + 1) == abs(pattern[j] - i)) {valid = false;break;}}if (!valid)continue;pattern[k - 1] = i;if (k == n)return 1;elseres += countSolution(k + 1, pattern);}return res;}};
上面这个例子, 包括下面的例子,都默认要求 n < 32
-------------------------方法2------------
public class Solution { static int result = 0; static int upperLimit = 0; public int totalNQueens(int n) { upperLimit = (1 << n)-1; result = 0; int row = 0; int ld = 0; int rd = 0; dfs(row,ld,rd); return result; } private static void dfs(int row, int ld, int rd) { if(row >= upperLimit){ result++; return; } int pos = upperLimit &(~(row|ld|rd)); int p = 0; while(pos > 0){ p = pos & (~pos+1); pos = pos-p; dfs(row+p,(ld+p)<<1,(rd+p)>>1); } } }
Mistakes:
背诵上面的代码吧。 人家还用了个main:
Learned:
首先是label的运用。可以直接跳出2层循环。
当然,不建议这样用,可以设置个标识,如果内层跳出了, 再跳第二层。
----------------------------3 rd Pass --------------------------
由于2D array 的值只有2个, 因此,我们可以用1D array 来表示它。
比如: int[ ] {3,1,4,2} 代表放置的地点分别为[1,3], [2,1], [3,4], [2,4] ( 第一个是index)
这么一来,我们用很简单的用数组表示了整个Board,而且在isValid函数里判断的时候会非常简洁,而且把输出Board单独隔离了出来
注意,我们刚开始的时候,在isValid中,依然去判断行,列, 对角线。 其实是不必要的。 只需要判断当前行之前的行,列即可。
因此,刚开始的时候,我们写成:
private boolean isValid(int cur) {
// no need to check col, check row
for (int i = 0; i < cur; i++)
if ( loc[i] == loc[cur])
return false;
// check diagonal \
for (int i = 0; i < cur; i++) {
int j = i + loc[cur] - cur; // new colum that is on diagonal
if ( j >= 0 && j < N && loc[j] != loc[cur])
return false;
}
// check diagonal /
for (int i = 0; i < cur; i++) {
int j = loc[cur] + cur - i;// new colum that is on diagonal /
if ( j >= 0 && j < N && loc[j] != loc[cur])
return false;
}
return true;
}
这样其实是不必要的, 只需要判断 x上的距离差和y轴上的距离差,绝对值相等即可。
public class Solution { int total = 0; public int totalNQueens(int n) { int[] loc = new int[n]; dfs(loc,0); return total; } private void dfs(int[] loc,int row) { if (row >= loc.length) { total++; return; } for (int i = 0; i < loc.length; i++) { loc[row] = i+1;// loc[i]==j, means that on board[i][j] =='Q' if (isValid( loc,row)) dfs(loc,row + 1); } } private boolean isValid(int[] loc,int cur) { for (int i = 0; i < cur; i++) if (loc[i] == loc[cur] || Math.abs(loc[i] - loc[cur]) == (cur - i)) return false; return true; } }
Learned:
1:
用1D 来代替2D array-------- 其实,退化来讲, 如果是一维的棋盘,上面只能有一个位置放Q的话。
我们也可以直接 用一个 变量 来记录其位置即可。
2:
对2D 的数组来讲, 要判断是其diagonal的值相等。只需要判断其 x 轴的差距, 是否和 y轴的差距相等即可。 (由于是2条对角线, 因此,要去 Abs)
51. N-Queens --- H !!!!
The n-queens puzzle is the problem of placing n
queens on an n x n
chessboard such that no two queens attack each other.
Given an integer n
, return all distinct solutions to the n-queens puzzle. You may return the answer in any order.
Each solution contains a distinct board configuration of the n-queens' placement, where 'Q'
and '.'
both indicate a queen and an empty space, respectively.
Example 1:

Input: n = 4 Output: [[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]] Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above
Example 2:
Input: n = 1 Output: [["Q"]]
Constraints:
1 <= n <= 9
--------------------2 nd pass----------------------
DFS ---------- Use 2D array
出现的问题,还是在于,测试diagonal的时候, 两条diagonal的表达有问题。
class Solution {public:vector<vector<string>> solveNQueens(int n) {vector<vector<char>> board(n, vector<char>(n, '.'));vector<vector<string>> res;dfs(board, res, 0);return res;}private:void dfs(vector<vector<char>>& board, vector<vector<string>>& res, int row) {int n = board.size();if (row == n) {vector<string> curRes;for (int i = 0; i < n; i++) {string tmp(board[i].begin(), board[i].end());curRes.push_back(tmp);}res.push_back(curRes);} else {for (int j = 0; j < n; j++) {board[row][j] = 'Q';if (isValid(board, row, j))dfs(board, res, row + 1);board[row][j] = '.';}}}bool isValid(vector<vector<char>>& board, int row, int col) {int n = board.size();// check each row ifor (int j = 0; j < n; j++) {if (j != col && board[row][j] == 'Q')return false;}// now check colum : colfor (int i = 0; i < n; i++) {if (i != row && board[i][col] == 'Q')return false;}// check diagonalfor (int i = 0; i < n; i++) {int j = i + (col - row);if (j >= 0 && j < n && i != row && board[i][j] == 'Q')return false;}// check reverse diagonalfor (int i = 0; i < n; i++) {int j = (col + row) - i;if (j >= 0 && j < n && i != row && board[i][j] == 'Q')return false;}return true;}};
--------------3rd pass---------------------
这里用了2D array, 如果用一维数组表示的话(类似于N-Queen II) ,
方法是:一维数组的下标表示横坐标(哪一行),而数组的值表示纵坐标(哪一列)。
Mistakes: