第一题:
Climbing Stairs
分析:简单DP, dp[i] = dp[i-1]+dp[i-2]
代码:
(C++版)
class Solution
{
public:
int climbStairs(int n)
{
int dp[50] = {0, 1, 2};
int i;
for (i = 3; i < 50; i++)
dp[i] = dp[i-1]+dp[i-2];
return dp[n];
}
};
第二题:
Longest Substring Without Repeating Characters
分析:用一个hash table保存每个字符上一次出现过的位置。从前往后扫描,假如发现字符上次出现过,就把当前子串的起始位置start移动到上次出现过的位置之后——这是为了保证从start到i的当前子串中没有任何重复字符。同时,由于start移动,当前子串的内容改变,start移动过程中经历的字符都要剔除。
代码:
(C++版)
class Solution
{
public:
int lengthOfLongestSubstring(string s)
{
int table[400];
int i, len = s.length(), max = 0, start = 0;
for (i = 0; i < 400; i++) table[i] = -1;
for (i = 0; i < len; i++)
{
if (table[s[i]] != -1)
{
while (start <= table[s[i]]) table[s[start++]] = -1;
}
if (i-start+1 > max) max = i-start+1;
table[s[i]] = i;
}
return max;
}
};
第三题:
Reverse Integer
分析:水题一只。
代码:
(C++版)
class Solution
{
public:
int reverse(int x)
{
int flag = 1;
if (x < 0) flag = -1, x = -x;
int ans = 0;
while (x > 0)
{
ans *= 10;
ans += x%10;
x /= 10;
}
return ans*flag;
}
};
第四题:
N-Queens
分析:N皇后问题。递归之。recursion
代码:
(C++版)
int col[100], row[100], back[100];
int arr[100][100];
vector<vector<string>> ans;
void recursion(int x, int n)
{
int i, j;
if (x > n)
{
vector<string> add;
for (i = 1; i <= n; i++)
{
string str = "";
for (j = 1; j <= n; j++)
str += arr[i][j] == 1 ? "Q" : ".";
add.push_back(str);
}
ans.push_back(add);
return ;
}
for (i = 1; i <= n; i++)
{
if (row[i] == 0 && col[n-x+i] == 0 && back[x+i-1] == 0)
{
row[i] = 1, col[n-x+i] = 1, back[x+i-1] = 1;
arr[x][i] = 1;
recursion(x+1, n);
row[i] = 0, col[n-x+i] = 0, back[x+i-1] = 0;
arr[x][i] = 0;
}
}
return ;
}
class Solution
{
public:
vector<vector<string> > solveNQueens(int n)
{
ans.clear();
recursion(1, n);
return ans;
}
};
第五题:
Largest Rectangle in Histogram
分析:先求出每个元素的左边界和右边界,然后遍历一遍即可,复杂度O(n^2)。
代码:
(C++版)
typedef struct NodeLeft
{
int left, right;
NodeLeft(int a,int b):left(a), right(b){}
}NodeLeft;
vector<NodeLeft> vec;
class Solution
{
public:
int largestRectangleArea(vector<int> &height)
{
int size = height.size();
int i, j;
vec.clear();
if (size == 0) return 0;
if (size == 1) return height[0];
NodeLeft add(0,0);
vec.push_back(add);
for (i = 1; i < size; i++)
{
j = i-1;
if (height[i] <= height[j])
{
while (height[i] <= height[j])
{
j = vec[j].left;
if (j == 0) break;
if (height[i] <= height[j-1]) j = j-1;
if (height[i] > height[j-1]) break;
}
add.left = j;
}
else add.left = i;
vec.push_back(add);
}
vec[size-1].right = size-1;
for (i = size-2; i >= 0; i--)
{
j = i+1;
if (height[i] <= height[j])
{
while (height[i] <= height[j])
{
j = vec[j].right;
if (j == size-1) break;
if (height[i] <= height[j+1]) j = j+1;
if (height[i] > height[j+1]) break;
}
vec[i].right = j;
}
else vec[i].right = i;
}
int max = 0;
for (i = 0; i < size; i++)
{
if (((vec[i].right-vec[i].left+1)*height[i]) > max)
max = (vec[i].right-vec[i].left+1)*height[i];
}
return max;
}
};
分析二:
可以用线性方法,维护一个高度递增的栈。如果遇到一个元素比当前栈顶元素高度小,那么出栈,并计算当前最大面积。如果栈为空,需要特殊考虑。
代码:
(C++版)
class Solution
{
public:
int largestRectangleArea(vector<int> &height)
{
stack<int> s;
int n = height.size();
int max_area = 0;
int tp;
int area_with_top;
int i = 0;
while (i < n)
{
if (s.empty() || height[s.top()] <= height[i])
s.push(i++);
else
{
tp = s.top();
s.pop();
area_with_top = height[tp] * (s.empty() ? i : i - s.top() - 1);
if (max_area < area_with_top)
max_area = area_with_top;
}
}
while (s.empty() == false)
{
tp = s.top();
s.pop();
area_with_top = height[tp] * (s.empty() ? i : i - s.top() - 1);
if (max_area < area_with_top)
max_area = area_with_top;
}
return max_area;
}
};
第六题:
Valid Palindrome
分析:回文,一开始看成只有字符了,没想到还有数字=、=。注意检测没有字符数字的情况。
代码:
(C++版)
class Solution
{
public:
bool isPalindrome(string s)
{
int i, j, len, flag = 0;
if (s == "") return true;
len = s.length();
i = 0, j = len-1;
for (i = 0; i < len; i++)
{
if (s[i] >= 'A' && s[i] <= 'Z') s[i] = 'a' + s[i]-'A', flag = 1;
if ((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= '0' && s[i] <= '9')) flag = 1;
}
if (flag == 0) return true;
i = 0;
while (i < j)
{
while (!((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= '0' && s[i] <= '9'))) i++;
while (!((s[j] >= 'a' && s[j] <= 'z') || (s[j] >= '0' && s[j] <= '9'))) j--;
if (s[i] != s[j]) return false;
i++, j--;
}
return true;
}
};
第七题:
Longest Valid Parentheses
分析:用一个栈和数组,在数组中把能组成()的对应的位置置为1,然后从数组中找连续的最长的1串。
代码:
(C++版)
int dp[100000];
int vec[100000];
class Solution
{
public:
int longestValidParentheses(string s)
{
int i, j = -1;
for (i = 0; i < 100000; i++) dp[i] = vec[i] = 0;
for (i = 0; s[i]; i++)
{
if (j == -1) vec[j+1] = i, j++;
else if(s[i] == ')')
{
if (s[vec[j]] == '(') dp[vec[j]] = 1, dp[i] = 1, j--;
else vec[j+1] = i, j++;
}
else vec[j+1] = i, j++;
}
int count = 0, maxnum = 0;
for (i = 0; s[i]; i++)
{
if (dp[i] == 0)
{
if (count > maxnum) maxnum = count;
count = 0;
}
else count++;
}
if (count > maxnum) maxnum = count;
return maxnum;
}
};
第八题:
Merge Intervals
分析:合并集合。在leetcode上好久没有1A了。。。此题1A。。。
代码:
(C++版)
/**
* 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:
static bool cmp(const Interval &a, const Interval &b)
{
return a.start < b.start;
}
vector<Interval> merge(vector<Interval> &intervals)
{
int i;
vector<Interval> ans;
ans.clear();
int size = intervals.size();
if (size == 0) return ans;
sort(intervals.begin(), intervals.end(), cmp);
Interval add;
add.start = intervals[0].start, add.end = intervals[0].end;
for (i = 1; i < size; i++)
{
if (intervals[i].start > add.end)
{
ans.push_back(add);
add.start = intervals[i].start, add.end = intervals[i].end;
}
else
{
if (intervals[i].end > add.end)
add.end = intervals[i].end;
}
}
ans.push_back(add);
return ans;
}
};
第九题:
Divide Two Integers
分析:logn,边界处理操蛋。
代码:
(C++版)
int ans;
class Solution
{
public:
static int divide(long long divident,long long divisor, long long num, int count)
{
if (divident >= (num + num))
{
divident = divident - num - num;
count *= 2;
ans += count;
num *= 2;
divide(divident, divisor, num, count);
}
else if (divident >= num)
{
divident -= num;
ans += count;
divide(divident, divisor, divisor, 1);
}
else if(divident >= (divisor+divisor))
{
divide(divident, divisor, divisor, 1);
}
else
{
while (divident >= divisor)
{
divident -= divisor;
ans += 1;
}
}
return ans;
}
int divide(int dividend, int divisor)
{
long long int div, divi;
div = dividend, divi = divisor;
int flag1 = 0, flag2 = 0;
if (divisor == 0) return 0;
if (dividend < 0) div = -div, flag1 = 1;
if (divisor < 0) divi = -divi, flag2 = 1;
ans = 0;
divide(div, divi,divi, 1);
if (flag1 != flag2) ans *= -1;
return ans;
}
};
第十题:
Palindrome Number
分析:题目说不能用额外内存,妈蛋,我以为类似于int i;这种都不行呢=、=
代码:
(C++版)
class Solution {
public:
bool isPalindrome(int x)
{
if (x < 0) return false;
int a = x;
int y = 0 ;
for(;a;a=a/10)
{
y = y*10 + a%10;
}
return (x==y);
}
};
第十一题
Valid Parentheses
分析:stack的使用。
代码:
(C++版)
char ch[100000];
class Solution
{
public:
bool isValid(string s)
{
int i, j = -1;
int len = s.length();
for (i = 0; i < len; i++)
{
if (j == -1) {j++, ch[j] = s[i];}
else if (s[i] == ')')
{
if (ch[j] == '(') j--;
else j++, ch[j] = s[i];
}
else if (s[i] == ']')
{
if (ch[j] == '[') j--;
else j++, ch[j] = s[i];
}
else if (s[i] == '}')
{
if (ch[j] == '{') j--;
else j++, ch[j] = s[i];
}
else j++, ch[j] = s[i];
}
if (j == -1) return true;
return false;
}
};
第十二题:
Spiral Matrix II
分析:螺旋矩阵,easy problem
代码:
(C++版)
class Solution
{
public:
vector<vector<int> > generateMatrix(int n)
{
int i, j, go = 1;
vector<vector<int>> ans;
ans.clear();
for (i = 0; i < n; i++)
{
vector<int> add;
for (j = 0; j < n; j++) add.push_back(0);
ans.push_back(add);
}
for (i = 0; i < (n+1)/2; i++)
{
for (j = i; j < n-i; j++) ans[i][j] = go++;
for (j = i+1; j < n-i; j++) ans[j][n-i-1] = go++;
for (j = n-i-1-1; j >= i; j--) ans[n-i-1][j] = go++;
for (j = n-i-2; j > i; j--) ans[j][i] = go++;
}
/*
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
cout << ans[i][j] << " ";
cout << endl;
}
*/
return ans;
}
};
第十三题:
Spiral Matrix
分析:和上题差不多。不过不是正方形了,而是换成矩形了。
代码:
(C++版)
class Solution
{
public:
vector<int> spiralOrder(vector<vector<int> > &matrix)
{
int m, n, i, j, count = 0;
vector<int> ans;
ans.clear();
m = matrix.size();
if (m == 0) return ans;
n = matrix[0].size();
for (i = 0; i < (m+1)/2; i++)
{
for (j = i; j < n-i; j++) ans.push_back(matrix[i][j]), count++;
for (j = i+1; j < m-i; j++) ans.push_back(matrix[j][n-i-1]), count++;
if (m-i-1 != i) for (j = n-i-2; j >= i; j--) ans.push_back(matrix[m-i-1][j]), count++;
if (i != n-i-1) for (j = m-i-2; j > i; j--) ans.push_back(matrix[j][i]), count++;
if (count == m*n) break;
}
/*
for (i = 0; i < int(ans.size()); i++)
cout << ans[i] << " " ;
cout << endl;
*/
return ans;
}
};
第十四题:
Search a 2D Matrix
分析:杨氏矩阵,复杂度 O(m+n)
代码:
(C++版)
class Solution
{
public:
bool searchMatrix(vector<vector<int> > &matrix, int target)
{
int n, m, i, j;
m = matrix.size();
if (m == 0) return false;
n = matrix[0].size();
for (i = 0; i < m;)
{
if (matrix[i][n-1] >= target)
{
for (j = n-1; j >= 0; j--)
{
if (matrix[i][j] == target) return true;
}
if (j < 0) return false;
}
else i++;
}
return false;
}
};
第十五题:
Binary Tree Inorder Traversal
分析:中序遍历。
代码:
(C++版)
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
vector<int> ans;
class Solution
{
public:
static void dfs(TreeNode *root)
{
if (root == NULL) return;
if (root->left) dfs(root->left);
ans.push_back(root->val);
if (root->right) dfs(root->right);
}
vector<int> inorderTraversal(TreeNode *root)
{
ans.clear();
dfs(root);
return ans;
}
};
第十六题:
Maximum Subarray
分析:贪心。
代码:
(C++版)
class Solution
{
public:
int maxSubArray(int A[], int n)
{
int max = -10000000, i, sum;
sum = 0;
for (i = 0; i < n; i++)
{
sum += A[i];
if (sum > max) max = sum;
if (sum < 0) sum = 0;
}
return max;
}
};
第十七题:
Minimum Depth of Binary Tree
分析:略水=、=
代码:
(C++版)
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
int ans;
void dfs(TreeNode *root, int depth)
{
if (root == NULL) return ;
if (root->left == NULL && root->right == NULL)
{
if (depth < ans) ans = depth;
return ;
}
if (root->left != NULL) dfs(root->left, depth+1);
if (root->right != NULL) dfs(root->right, depth+1);
return ;
}
class Solution
{
public:
int minDepth(TreeNode *root)
{
if (root == NULL) return 0;
if (root->left == NULL && root->right == NULL) return 1;
ans = 100000000;
dfs(root, 1);
return ans;
}
};
第十八题:
Integer to Roman
分析:慢慢搞。数字转化为罗马数字
代码:
(C++版)
class Solution
{
public:
string intToRoman(int num)
{
char ch[7] = {'I', 'V', 'X', 'L', 'C', 'D', 'M'};
string str = "";
int a, i;
while (num > 0)
{
if (num >= 1000)
{
a = num/1000;
for (i = 0; i < a; i++) str += ch[6];
num %= 1000;
}
else if (num >= 100)
{
a = num / 100;
if (a <= 3) for (i = 0; i < a; i++) str += ch[4];
else if (a <= 5) str += a == 4 ? "CD" : "D";
else if (a <= 8) {str += 'D'; for (i = 0; i < a-5; i++) str += 'C';}
else str += "CM";
num %= 100;
}
else if (num >= 10)
{
a = num / 10;
if (a <= 3) for (i = 0; i < a; i++) str += 'X';
else if (a <= 5) str += a == 4 ? "XL" : "L";
else if (a <= 8) {str += 'L'; for (i = 0; i < a-5; i++) str += 'X';}
else str += "XC";
num %= 10;
}
else
{
a = num;
if (a <= 3) for (i = 0; i < a; i++) str += 'I';
else if (a <= 5) str += a == 4 ? "IV" : "V";
else if (a <= 8) {str += 'V'; for (i = 0; i < a-5; i++) str += 'I';}
else str += "IX";
num = 0;
}
}
return str;
}
};
第十九题:
Sort Colors
分析:two pointers算法
代码:
(C++版)
#define SWAP(a, b) int temp = a; a = b; b = temp;
class Solution
{
public:
void sortColors(int A[], int n)
{
int i, p, q;
p = 0, q = n-1;
for (i = 0; i <= q; )
{
if (A[i] == 0)
{
if (i == p) i++;
else { SWAP(A[i], A[p]) p++;}
}
else if (A[i] == 2)
{
if (i == q) break;
else { SWAP(A[i], A[q]) q--;}
}
else i++;
}
}
};
第二十题:
Remove Duplicates from Sorted List II
分析:指针是硬伤啊=。=
代码:
(C++版)
class Solution
{
public:
ListNode *deleteDuplicates(ListNode *head)
{
ListNode *ans(0), *pre(0);
int flag = 0;
pre = (ListNode *)malloc(sizeof(ListNode));
ans = pre;
pre->next = NULL;
if (head == NULL) return NULL;
if (head->next == NULL) return head;
while (head != NULL)
{
if (head->next != NULL && head->next->val == head->val)
{
int va = head->val;
while (head != NULL && head->val == va) { head = head->next;}
}
else
{
pre->next = head;
head = head->next;
pre = pre->next;
pre->next = NULL;
}
}
return ans->next;
}
};