1、Minimum Path Sum
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
Note: You can only move either down or right at any point in time.
寻找最短路径,移动只能向下或者向右,动态规划的思想。申请一个m*n的数组,保存0,0到达该点的路径最短长度。 int minPathSum(vector<vector<int> > &grid) {
int m = grid.size();
if(m==0){
return 0;
}
int n = grid[0].size();
if(n==0){
return 0;
}
vector<vector<int>> vec(m,vector<int>(n));
vec[0][0] = grid[0][0];
for(int i = 1;i<m;i++){
vec[i][0] = vec[i-1][0]+grid[i][0];
}
for(int j = 1;j<n;j++){
vec[0][j] = vec[0][j-1] + grid[0][j];
}
for(int i = 1;i<m;i++){
for(int j = 1;j<n;j++){
vec[i][j] = vec[i-1][j]>vec[i][j-1]?vec[i][j-1]:vec[i-1][j];
vec[i][j] += grid[i][j];
}
}
return vec[m-1][n-1];
}
2、Add Binary
int minPathSum(vector<vector<int> > &grid) {
int m = grid.size();
if(m==0){
return 0;
}
int n = grid[0].size();
if(n==0){
return 0;
}
vector<vector<int>> vec(m,vector<int>(n));
vec[0][0] = grid[0][0];
for(int i = 1;i<m;i++){
vec[i][0] = vec[i-1][0]+grid[i][0];
}
for(int j = 1;j<n;j++){
vec[0][j] = vec[0][j-1] + grid[0][j];
}
for(int i = 1;i<m;i++){
for(int j = 1;j<n;j++){
vec[i][j] = vec[i-1][j]>vec[i][j-1]?vec[i][j-1]:vec[i-1][j];
vec[i][j] += grid[i][j];
}
}
return vec[m-1][n-1];
}
Given two binary strings, return their sum (also a binary string).
For example,
a = "11"
b = "1"
Return "100"
.
本来是一道简单的题目,没想到当时我写了这么多代码,其实是可以直接string的append方法,然后reverse方法进行reverse的。我用的栈存储,然后提取出来,是麻烦了一些。。。
string addBinary(string a, string b) {
int lena = a.size();
int lenb = b.size();
if(lena == 0){
return b;
}
if(lenb == 0){
return a;
}
bool add = false;
stack<char> ret;
while(lena>0&&lenb>0){
if(a[lena-1]=='1'&&b[lenb-1]=='1'&&add){
add = true;
ret.push('1');
}
else if(a[lena-1]=='1'&&b[lenb-1]=='1'&&!add){
add = true;
ret.push('0');
}
else if(a[lena-1]=='0'&&b[lenb-1]=='0'&&!add){
add = false;
ret.push('0');
}
else if(a[lena-1]=='0'&&b[lenb-1]=='0'&&add){
add = false;
ret.push('1');
}
else if((a[lena-1]=='1'^b[lenb-1]=='1')&&add){
add = true;
ret.push('0');
}
else{
add = false;
ret.push('1');
}
lena--;
lenb--;
}
while(lena>0){
if(a[lena-1]=='1'&&add){
add = true;
ret.push('0');
}
else if((a[lena-1]=='1'&&!add)||(a[lena-1]=='0'&&add)){
add = false;
ret.push('1');
}
else{
add=false;
ret.push('0');
}
lena--;
}
while(lenb>0){
if(b[lenb-1]=='1'&&add){
add = true;
ret.push('0');
}
else if((b[lenb-1]=='1'&&!add)||(b[lenb-1]=='0'&&add)){
add = false;
ret.push('1');
}
else{
add=false;
ret.push('0');
}
lenb--;
}
if(add){
ret.push('1');
}
string temp = "";
while(!ret.empty()){
temp += ret.top();
ret.pop();
}
return temp;
}
3、Valid Number
string addBinary(string a, string b) {
int lena = a.size();
int lenb = b.size();
if(lena == 0){
return b;
}
if(lenb == 0){
return a;
}
bool add = false;
stack<char> ret;
while(lena>0&&lenb>0){
if(a[lena-1]=='1'&&b[lenb-1]=='1'&&add){
add = true;
ret.push('1');
}
else if(a[lena-1]=='1'&&b[lenb-1]=='1'&&!add){
add = true;
ret.push('0');
}
else if(a[lena-1]=='0'&&b[lenb-1]=='0'&&!add){
add = false;
ret.push('0');
}
else if(a[lena-1]=='0'&&b[lenb-1]=='0'&&add){
add = false;
ret.push('1');
}
else if((a[lena-1]=='1'^b[lenb-1]=='1')&&add){
add = true;
ret.push('0');
}
else{
add = false;
ret.push('1');
}
lena--;
lenb--;
}
while(lena>0){
if(a[lena-1]=='1'&&add){
add = true;
ret.push('0');
}
else if((a[lena-1]=='1'&&!add)||(a[lena-1]=='0'&&add)){
add = false;
ret.push('1');
}
else{
add=false;
ret.push('0');
}
lena--;
}
while(lenb>0){
if(b[lenb-1]=='1'&&add){
add = true;
ret.push('0');
}
else if((b[lenb-1]=='1'&&!add)||(b[lenb-1]=='0'&&add)){
add = false;
ret.push('1');
}
else{
add=false;
ret.push('0');
}
lenb--;
}
if(add){
ret.push('1');
}
string temp = "";
while(!ret.empty()){
temp += ret.top();
ret.pop();
}
return temp;
}
Validate if a given string is numeric.
Some examples:
"0"
=> true
" 0.1 "
=> true
"abc"
=> false
"1 a"
=> false
"2e10"
=> true
Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.
情况非常多在字符串之前有空格需要去掉,科学表示法也是正确的,小数也是正确的,多个小数点问题。
这道题目,我是参考的网上的方案,具体的方案,在这里。
用了有限状态机,然后对于每个字符有相关的转换关系。
有限状态机 TODO
http://www.cnblogs.com/chasuner/p/validNumber.html
http://haiyangxu.github.io/posts/2014/2014-05-06-LeetCode-Valid-Number.html
enum Op{
Operator, //0
Digit, // 1
E, // 2
Dot, //3
Space,// 4
Invalid
};
int table[][5] = {
{1,2,-1,8,-1},
{-1,2,-1,8,-1},
{-1,2,4,3,-1},
{-1,7,4,-1,-1},
{5,6,-1,-1,-1},
{-1,6,-1,-1,-1},
{-1,6,-1,-1,-1},
{-1,7,4,-1,-1},
{-1,9,-1,-1,-1},
{-1,9,4,-1,-1}
};
class Solution {
public:
bool trim(string& s) {
int start = 0;
int end = s.size() - 1;
while(start <= end && s[start] == ' ') start++;
while(end >= 0 && s[end] == ' ') end--;
if(end >= start) s = s.substr(start , end - start + 1);
else return false;
return true;
}
Op getOp(char ch) {
if(ch == '+' || ch == '-') return Operator;
if(ch >= '0' && ch <= '9') return Digit;
if(ch == 'e') return E;
if(ch == '.') return Dot;
if(ch == ' ') return Space;
return Invalid;
}
bool isNumber(const char *s) {
string str = s;
if(!trim(str)) return false;
int pos = 0;
int size = str.size();
int state = 0;
while(pos < size) {
char ch = str[pos];
Op x = getOp(ch);
if(x == Invalid) return false;
state = table[state][(int)x];
if(state == -1) return false;
pos++;
}
return state == 2 || state == 6 || state == 7 || state == 3 || state == 9;
}
};
4、
enum Op{
Operator, //0
Digit, // 1
E, // 2
Dot, //3
Space,// 4
Invalid
};
int table[][5] = {
{1,2,-1,8,-1},
{-1,2,-1,8,-1},
{-1,2,4,3,-1},
{-1,7,4,-1,-1},
{5,6,-1,-1,-1},
{-1,6,-1,-1,-1},
{-1,6,-1,-1,-1},
{-1,7,4,-1,-1},
{-1,9,-1,-1,-1},
{-1,9,4,-1,-1}
};
class Solution {
public:
bool trim(string& s) {
int start = 0;
int end = s.size() - 1;
while(start <= end && s[start] == ' ') start++;
while(end >= 0 && s[end] == ' ') end--;
if(end >= start) s = s.substr(start , end - start + 1);
else return false;
return true;
}
Op getOp(char ch) {
if(ch == '+' || ch == '-') return Operator;
if(ch >= '0' && ch <= '9') return Digit;
if(ch == 'e') return E;
if(ch == '.') return Dot;
if(ch == ' ') return Space;
return Invalid;
}
bool isNumber(const char *s) {
string str = s;
if(!trim(str)) return false;
int pos = 0;
int size = str.size();
int state = 0;
while(pos < size) {
char ch = str[pos];
Op x = getOp(ch);
if(x == Invalid) return false;
state = table[state][(int)x];
if(state == -1) return false;
pos++;
}
return state == 2 || state == 6 || state == 7 || state == 3 || state == 9;
}
};
Plus One
Given a non-negative number represented as an array of digits, plus one to the number.
The digits are stored such that the most significant digit is at the head of the list.
用数组表示的一个数,然后加一,考虑的情况如果都是9的情况,或者说大部分是9的情况。
vector<int> plusOne(vector<int> &digits) {
int i;
for(i = digits.size() - 1;i >= 0;--i){
if(digits[i] != 9){
++digits[i];
return digits;
}
else {
digits[i] = 0;
}
}
//各位全是9
if(i < 0) {
digits.insert(digits.begin(),1);//头部插入1
}
return digits;
}
5、Text Justification
Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified.
You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' '
when necessary so that each line has exactly Lcharacters.
Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right.
For the last line of text, it should be left justified and no extra space is inserted between words.
For example,
words: ["This", "is", "an", "example", "of", "text", "justification."]
L: 16
.
Return the formatted lines as:
[ "This is an", "example of text", "justification. " ]
Note: Each word is guaranteed not to exceed L in length.
- A line other than the last line might contain only one word. What should you do in this case?
In this case, that line should be left-justified.
class Solution {
public:
/**
* 字符串处理,贪心,平均空格,最后一行的处理
* */
vector<string> fullJustify(vector<string> &words, int L) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
vector<string>res;
int len = words.size(), i = 0;
while(i < len)
{
//if(words[i].size() == 0){i++; continue;}
int rowlen = 0, j = i;
while(j < len && rowlen + words[j].size() <= L)
rowlen += (words[j++].size() + 1);
//j-i是该行放入单词的数目
if(j - i == 1)
{//处理放入一个单词的特殊情况
res.push_back(words[i]);
addSpace(res.back(), L - words[i].size());
i = j; continue;
}
//charaLen是当前行字母总长度
int charaLen = rowlen - (j - i);
//平均每个单词后的空格,j < len 表示不是最后一行
int meanSpace = j < len ? (L - charaLen) / (j - i - 1) : 1;
//多余的空格
int leftSpace = j < len ? (L - charaLen) % (j - i - 1) : L - charaLen - (j - i -1);
string tmp;
for(int k = i; k < j - 1; k++)
{
tmp += words[k];
addSpace(tmp, meanSpace);
if(j < len && leftSpace > 0)
{
tmp.push_back(' ');
leftSpace--;
}
}
tmp += words[j - 1];//放入最后一个单词
if(leftSpace > 0)addSpace(tmp, leftSpace); //对最后一行
res.push_back(tmp);
i = j;
}
return res;
}
void addSpace(string &s, int count)
{
for(int i = 1; i <= count; i++)
s.push_back(' ');
}
};
class Solution {
public:
/**
* 字符串处理,贪心,平均空格,最后一行的处理
* */
vector<string> fullJustify(vector<string> &words, int L) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
vector<string>res;
int len = words.size(), i = 0;
while(i < len)
{
//if(words[i].size() == 0){i++; continue;}
int rowlen = 0, j = i;
while(j < len && rowlen + words[j].size() <= L)
rowlen += (words[j++].size() + 1);
//j-i是该行放入单词的数目
if(j - i == 1)
{//处理放入一个单词的特殊情况
res.push_back(words[i]);
addSpace(res.back(), L - words[i].size());
i = j; continue;
}
//charaLen是当前行字母总长度
int charaLen = rowlen - (j - i);
//平均每个单词后的空格,j < len 表示不是最后一行
int meanSpace = j < len ? (L - charaLen) / (j - i - 1) : 1;
//多余的空格
int leftSpace = j < len ? (L - charaLen) % (j - i - 1) : L - charaLen - (j - i -1);
string tmp;
for(int k = i; k < j - 1; k++)
{
tmp += words[k];
addSpace(tmp, meanSpace);
if(j < len && leftSpace > 0)
{
tmp.push_back(' ');
leftSpace--;
}
}
tmp += words[j - 1];//放入最后一个单词
if(leftSpace > 0)addSpace(tmp, leftSpace); //对最后一行
res.push_back(tmp);
i = j;
}
return res;
}
void addSpace(string &s, int count)
{
for(int i = 1; i <= count; i++)
s.push_back(' ');
}
};
6、Sqrt(x)
Implement int sqrt(int x)
.
Compute and return the square root of x.
sqrt实现,这里用了二分查找的方式,在0,x+1/2之间进行计算 int sqrt(int x) {
if(x<=0){
return NULL;
}
unsigned long long left = 0;
unsigned long long right = (x+1)/2;
unsigned long long mid = 0;
while(left<right){
mid = (right + left)/2;
unsigned long long value = mid*mid;
if(value == x){
return mid;
}
else if(value > x){
right = mid - 1;
}
else{
left = mid + 1;
}
}
if(right*right>x){
return right - 1;
}
else{
return right;
}
}
int sqrt(int x) {
if(x<=0){
return NULL;
}
unsigned long long left = 0;
unsigned long long right = (x+1)/2;
unsigned long long mid = 0;
while(left<right){
mid = (right + left)/2;
unsigned long long value = mid*mid;
if(value == x){
return mid;
}
else if(value > x){
right = mid - 1;
}
else{
left = mid + 1;
}
}
if(right*right>x){
return right - 1;
}
else{
return right;
}
}
7、Climbing Stairs
You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
类似青蛙跳,动态规划。 int climbStairs(int n) {
if(n==1){
return 1;
}
int first = 1;
int second = 1;
int i = 1;
int ret = 0;
while(i<n){
ret = first + second;
first = second;
second = ret;
i++;
}
return ret;
}
8、Unique Paths&&
int climbStairs(int n) {
if(n==1){
return 1;
}
int first = 1;
int second = 1;
int i = 1;
int ret = 0;
while(i<n){
ret = first + second;
first = second;
second = ret;
i++;
}
return ret;
}
Unique Paths II
A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).
The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).
How many possible unique paths are there?
Above is a 3 x 7 grid. How many possible unique paths are there?
Note: m and n will be at most 100.
动态规划 int uniquePaths(int m, int n) {
if(m==0||n==0){
return 0;
}
vector<vector<int>> vec(m,vector<int>(n));
for(int i =0;i<m;i++){
vec[i][n-1] = 1;
}
for(int i=0;i<n;i++){
vec[m-1][i] = 1;
}
for(int i=m-2;i>=0;i--){
for(int j = n-2;j>=0;j--){
vec[i][j] = vec[i+1][j]+vec[i][j+1];
}
}
return vec[0][0];
}
int uniquePaths(int m, int n) {
if(m==0||n==0){
return 0;
}
vector<vector<int>> vec(m,vector<int>(n));
for(int i =0;i<m;i++){
vec[i][n-1] = 1;
}
for(int i=0;i<n;i++){
vec[m-1][i] = 1;
}
for(int i=m-2;i>=0;i--){
for(int j = n-2;j>=0;j--){
vec[i][j] = vec[i+1][j]+vec[i][j+1];
}
}
return vec[0][0];
}
Follow up for "Unique Paths":
Now consider if some obstacles are added to the grids. How many unique paths would there be?
An obstacle and empty space is marked as 1
and 0
respectively in the grid.
For example,
There is one obstacle in the middle of a 3x3 grid as illustrated below.
[ [0,0,0], [0,1,0], [0,0,0] ]
The total number of unique paths is 2
.
Note: m and n will be at most 100.
还是继续动态规划,只是在1的位置不进行加就可以了。 int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) {
int m = obstacleGrid.size();
if(m==0){
return 0;
}
int n = obstacleGrid[0].size();
if(n==0){
return 0;
}
vector<vector<int>> vec(m,vector<int>(n));
bool isobs = false;
for(int i =m-1;i>=0;i--){
if(obstacleGrid[i][n-1]==1||isobs){
vec[i][n-1] = 0;
isobs = true;
}
else
vec[i][n-1] = 1;
}
isobs = false;
for(int i=n-1;i>=0;i--){
if(obstacleGrid[m-1][i]==1||isobs){
vec[m-1][i] = 0;
isobs = true;
}
else
vec[m-1][i] = 1;
}
if(m==1||n==1){
return vec[0][0];
}
for(int i=m-2;i>=0;i--){
for(int j = n-2;j>=0;j--){
if(obstacleGrid[i][j]==1){
vec[i][j] = 0;
}
else{
vec[i][j] = vec[i+1][j]+vec[i][j+1];
}
}
}
return vec[0][0];
}
int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) {
int m = obstacleGrid.size();
if(m==0){
return 0;
}
int n = obstacleGrid[0].size();
if(n==0){
return 0;
}
vector<vector<int>> vec(m,vector<int>(n));
bool isobs = false;
for(int i =m-1;i>=0;i--){
if(obstacleGrid[i][n-1]==1||isobs){
vec[i][n-1] = 0;
isobs = true;
}
else
vec[i][n-1] = 1;
}
isobs = false;
for(int i=n-1;i>=0;i--){
if(obstacleGrid[m-1][i]==1||isobs){
vec[m-1][i] = 0;
isobs = true;
}
else
vec[m-1][i] = 1;
}
if(m==1||n==1){
return vec[0][0];
}
for(int i=m-2;i>=0;i--){
for(int j = n-2;j>=0;j--){
if(obstacleGrid[i][j]==1){
vec[i][j] = 0;
}
else{
vec[i][j] = vec[i+1][j]+vec[i][j+1];
}
}
}
return vec[0][0];
}
9、Permutation Sequence
The set [1,2,3,…,n]
contains a total of n! unique permutations.
By listing and labeling all of the permutations in order,
We get the following sequence (ie, for n = 3):
"123"
"132"
"213"
"231"
"312"
"321"
Given n and k, return the kth permutation sequence.
Note: Given n will be between 1 and 9 inclusive.
主要是对n的全排列进行计数,然后对n-0的各个全排列进行技术
从最高位开始一个一个确认该位是什么,利用了k模i的全排列的个数。
class Solution {
public:
/*
这个题耗费的时间比较多
主要出现问题在,k需要先进行-1操作,这样保证初始是0,及第一个元素
比如,2,2的例子
12
21
如果是2
如果不减一的话,那就得到倍数是2,那就是第三个数,这是错误的
*/
string getPermutation(int n, int k) {
string ret;
vector<int> vec(n-1);
map<int,int> nmap;
map<int,int> vmap;
int num = 0;
int i = 0;
for(i=1;i<=n;i++){
vmap[i]=1;
}
i = n-1;
k--;
while(i>0){
int x = getvalue(i);
nmap[i] = k/x;//第i位需要第几个元素
k = k%x;
i--;
}
map<int,int>::iterator iter;
for(i = n-1;i>0;i--){
if(nmap[i]==0){
ret += '0'+vmap.begin()->first;//添加该首个元素
iter = vmap.begin();
vmap.erase(iter);
}
else{
iter = vmap.begin();//确认是第几个元素
for(int j=0;j<nmap[i];j++){
iter++;
}
ret += '0'+iter->first;
vmap.erase(iter);
}
}
ret += '0' + vmap.begin()->first;
return ret;
}
int getvalue(int n){
if(n == 1||n==0){
return 1;
}else{
return n*getvalue(n-1);
}
}
};
10、Spiral Matrix I II
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
For example,
Given the following matrix:
[ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]
You should return [1,2,3,6,9,8,7,4,5]
.
vector<int> spiralOrder(vector<vector<int> > &matrix) {
vector<int> result;
if (matrix.empty()) return result;
int beginX = 0, endX = matrix[0].size() - 1;
int beginY = 0, endY = matrix.size() - 1;
while (true) {
// From left to right
for (int i = beginX; i <= endX; ++i)
result.push_back(matrix[beginY][i]);
if (++beginY > endY) break;
// From top down
for (int i = beginY; i <= endY; ++i)
result.push_back(matrix[i][endX]);
if (beginX > --endX) break;
// From right to left
for (int i = endX; i >= beginX; --i)
result.push_back(matrix[endY][i]);
if (beginY > --endY) break;
// From bottom up
for (int i = endY; i >= beginY; --i)
result.push_back(matrix[i][beginX]);
if (++beginX > endX) break;
}
return result;
}
vector<int> spiralOrder(vector<vector<int> > &matrix) {
vector<int> result;
if (matrix.empty()) return result;
int beginX = 0, endX = matrix[0].size() - 1;
int beginY = 0, endY = matrix.size() - 1;
while (true) {
// From left to right
for (int i = beginX; i <= endX; ++i)
result.push_back(matrix[beginY][i]);
if (++beginY > endY) break;
// From top down
for (int i = beginY; i <= endY; ++i)
result.push_back(matrix[i][endX]);
if (beginX > --endX) break;
// From right to left
for (int i = endX; i >= beginX; --i)
result.push_back(matrix[endY][i]);
if (beginY > --endY) break;
// From bottom up
for (int i = endY; i >= beginY; --i)
result.push_back(matrix[i][beginX]);
if (++beginX > endX) break;
}
return result;
}
Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order.
For example,
Given n = 3
,
[ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]我个人觉得1-n^2这个比较简单。
class Solution {
public:
vector<vector<int> > generateMatrix(int n) {
vector<vector<int>> vec(n,vector<int>(n));
int top = 0;
int buttom = n-1;
int left = 0;
int right = n-1;
int value = 1;
while(top<buttom){
for(int i=left;i<right;i++){
vec[top][i]=value++;
}
for(int i = top;i<buttom;i++){
vec[i][right] = value++;
}
for(int i = right;i>left;i--){
vec[buttom][i] = value++;
}
for(int i = buttom;i>top;i--){
vec[i][left] = value++;
}
top++;
buttom--;
left++;
right--;
}
if(top == buttom){
vec[top][buttom]=value;
}
return vec;
}
};
class Solution {
public:
vector<vector<int> > generateMatrix(int n) {
vector<vector<int>> vec(n,vector<int>(n));
int top = 0;
int buttom = n-1;
int left = 0;
int right = n-1;
int value = 1;
while(top<buttom){
for(int i=left;i<right;i++){
vec[top][i]=value++;
}
for(int i = top;i<buttom;i++){
vec[i][right] = value++;
}
for(int i = right;i>left;i--){
vec[buttom][i] = value++;
}
for(int i = buttom;i>top;i--){
vec[i][left] = value++;
}
top++;
buttom--;
left++;
right--;
}
if(top == buttom){
vec[top][buttom]=value;
}
return vec;
}
};