Convert Sorted Array to Binary Search Tree
分析:把一个排序数组转化为BST,由于基本功不扎实=。=写了挺长时间才AC。。。
代码:
# Definition for a binary tree node
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
# @param num, a list of integers
# @return a tree node
@staticmethod
def work(root, left, right, num):
if right < left:
return
mid = (left + right) // 2 # mid = 0
if mid-1 >= left:
add = TreeNode(num[(left+mid-1)//2])
root.left = add
Solution.work(root.left, left, mid-1, num)
if mid + 1 <= right:
add = TreeNode(num[(mid+1+right)//2])
root.right = add
Solution.work(root.right, mid+1, right, num)
def sortedArrayToBST(self, num):
size = len(num)
if size == 0: return None
root = TreeNode(num[(size-1)//2])
ans = root
Solution.work(root, 0, size-1, num)
return ans
第二题:
Letter Combinations of a Phone Number
分析:
坑爹啊。我还以为和手机上的按键方式一样呢。。。谁知竟然是个水题。浪费感情。。。简单递归一下就好了。
代码:
class Solution:
# @return a list of strings, [s1, s2]
ans = []
@staticmethod
def work(mapping, num, add, digits, index):
if index == len(digits):
Solution.ans.append(add)
return
for i in range(num[int(digits[index])]):
temp = add
add = add + mapping[int(digits[index])][i]
Solution.work(mapping, num, add, digits, index+1)
add = temp
def letterCombinations(self, digits):
mapping = [ [" "],[""],["a", "b", "c"],
["d", "e", "f"], ["g", "h", "i"],
["j", "k", "l"], ["m", "n", "o"],
["p", "q", "r", "s"], ["t", "u", "v"],
["w", "x", "y", "z"]
]
num = [1, 0, 3, 3, 3, 3, 3, 4, 3, 4]
add = ""
Solution.work(mapping, num, add, digits, 0)
return Solution.ans
第三题:
4Sum
分析:two pointers算法+O(n*n)循环。 所以复杂度是O(n^3), 用python没过。用C++过了。可能是由于python执行效率不如C++的原因。。。
代码:
bool cmp(vector<int> a, vector<int> b)
{
int i;
for (i = 0; i < 4; i++)
{
if (a[i] != b[i])
return a[i] < b[i];
}
return true;
}
class Solution
{
public:
vector<vector<int> > fourSum(vector<int> &num, int target)
{
int len, i, j, k, tar, m, n, sum2;
int visit[1010];
vector<vector<int>> ans;
for (i = 0; i < 1010; i++) visit[i] = 1;
sort(num.begin(), num.end());
ans.clear();
len = num.size();
if (len < 4)
return ans;
if (num[0] + num[1] + num[2] + num[3] > target)
return ans;
if (num[len-1] + num[len-2] + num[len-3] + num[len-4] < target)
return ans;
for (i = 0; i < len; i++)
{
for (j = i+1; j < len; j++)
{
sum2 = num[i] + num[j];
tar = target - sum2;
m = j + 1, n = len - 1;
while (true)
{
if (m >= n)
break;
if (num[m] + num[n] == tar)
{
vector<int> add;
add.push_back(num[i]);
add.push_back(num[j]);
add.push_back(num[m]);
add.push_back(num[n]);
ans.push_back(add);
m++, n--;
}
else if (num[m] + num[n] < tar)
m++;
else n--;
}
}
}
sort(ans.begin(), ans.end(), cmp);
len = ans.size();
for (i = 0; i < len; i++)
{
for (j = i + 1; j < len; j++)
{
for (k = 0; k < 4; k++)
{
if (ans[i][k] != ans[j][k]) break;
}
if (k == 4) visit[j] = 0;
}
}
vector<vector<int>> ret;
ret.clear();
for (i = 0; i < len; i++)
{
if (visit[i])
ret.push_back(ans[i]);
}
return ret;
}
};
第四题:
3Sum Closest
分析:从所给数组中找出3个元素,使其和与target相距最近。返回这个和。O(n*n),用到“双指针”法。
代码:
class Solution:
# @return an integer
def threeSumClosest(self, num, target):
ret = -100000000
num = sorted(num)
for i in range(len(num)-2):
j, k = [i+1, len(num)-1]
while j < k:
tar = num[i] + num[j] + num[k]
if int(abs(tar - target)) < int(abs(ret - target)):
ret = tar
if tar == target:
return target
elif tar < target:
j = j + 1
else:
k = k - 1
return ret
第五题:
Sqrt(x)
分析:sqrt的实现。用二分即可。
代码:
class Solution:
# @param x, an integer
# @return an integer
def sqrt(self, x):
if x == 0 or x == 1:
return x
left, right = [0, x]
# mid = (left + right) // 2
while left < right:
mid = (left + right) // 2
if mid * mid == x:
return mid
elif mid * mid > x:
right = mid - 1
else:
left = mid + 1
if left * left <= x:
return left
return left - 1
第六题:
Search for a Range
分析:二分即可。
代码:
class Solution:
l, r = [-1, -1]
# @param A, a list of integers
# @param target, an integer to be searched
# @return a list of length 2, [index1, index2]
@staticmethod
def search(left, right, A, target):
if left > right:
return
mid = (left + right) // 2
if A[mid] == target:
if mid < Solution.l:
Solution.l = mid
if mid > Solution.r:
Solution.r = mid
Solution.search(left, mid - 1, A, target)
Solution.search(mid + 1, right, A, target)
elif A[mid] < target:
Solution.search(mid + 1, right, A, target)
else:
Solution.search(left, mid - 1, A, target)
def searchRange(self, A, target):
Solution.l, Solution.r = [10000000, -1]
Solution.search(0, len(A)-1, A, target)
if Solution.l == 10000000 and Solution.r == -1:
return [-1, -1]
return [Solution.l, Solution.r]
第七题:
Pascal's Triangle II
分析:简单帕斯卡三角
代码:
class Solution:
# @return a list of integers
def getRow(self, rowIndex):
rowIndex = rowIndex + 1
ans = []
for i in range(rowIndex):
ans.append(1)
ans[0] = 1
if rowIndex == 1: return ans
ans[1] = 1
if rowIndex == 2: return ans
pre = 1
for i in range(3, rowIndex+1):
for j in range(i-2):
temp = ans[j+1] + pre
pre = ans[j+1]
ans[j+1] = temp
return ans
第八题:
Subsets
分析:随手DFS一下即可。
代码:
vector<int> add;
vector<vector<int>> ans;
int len;
void work(int index, int num, int count, vector<int>& S)
{
int i;
if (num == count) { ans.push_back(add); return ;}
if (index >= len) return ;
for (i = index; i < len; i++)
{
add.push_back(S[i]);
work(i+1, num, count+1, S);
add.pop_back();
}
return ;
}
class Solution
{
public:
vector<vector<int> > subsets(vector<int> &S)
{
int i;
len = S.size();
sort(S.begin(), S.end());
ans.clear();
add.clear();
ans.push_back(add);
for (i = 0; i < len; i++)
{
add.clear();
work(0, i+1, 0, S);
}
return ans;
}
};
第九题:
Minimum Path Sum
分析:水DP
代码:(C++)
int dp[1010][1010];
int a[1010][1010];
class Solution
{
public:
int minPathSum(vector<vector<int> > &grid)
{
int i, j, m, n;
m = grid.size(), n = grid[0].size();
for (i = 0; i < 1010; i++)
for (j = 0; j < 1010; j++)
dp[i][j] = a[i][j] = 199999999;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
a[i+1][j+1] = grid[i][j];
a[0][1] = a[1][0] = dp[0][1] = dp[1][0] = 0;
for (i = 1; i <= m; i++)
for (j = 1; j <= n; j++)
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + a[i][j];
return dp[m][n];
}
};
第十题:
Gas Station
分析:two pointers算法。
代码:(C++)//写了一发python竟然RE,然后对照着写了一发C++, AC。。。
class Solution {
public:
int canCompleteCircuit(vector<int> &gas, vector<int> &cost)
{
int ans = 0, i, j, size = cost.size();
for (i = 0; i < size; i++)
ans += gas[i] - cost[i];
if (ans < 0) return -1;
for (i = 0; i < size; i++)
if (gas[i] >= cost[i]) break;
j = i - 1;
ans = 0;
if (j < 0) j = size - 1;
while (i != j)
{
ans += gas[i] - cost[i];
if (ans < 0)
{
while (ans < 0)
{
ans += gas[j] - cost[j];
j = j - 1;
if (j < 0) j = size - 1;
}
}
i = i + 1;
if (i == size) i = 0;
}
return j + 1 == size ? 0 : j + 1;
}
};
第十一题:
Substring with Concatenation of All Words
分析:要求串联出现,所以用一个map统计一下频率,用C++很方便,直接写C非常麻烦。。。
代码:
class Solution
{
public:
vector<int> findSubstring(string S, vector<string> &L)
{
int size = L.size(), i, j, cnt;
int wordSize;
int len = S.length();
vector<int> result;
result.clear();
if (size <= 0) return vector<int>();
map<string, int> wordCount;
wordSize = L[0].size();
for (i = 0; i < size; i++)
wordCount[L[i]]++;
map<string, int> counting;
for (i = 0; i <= (int)S.length() - (size * wordSize); i++)
{
counting.clear();
for (j = 0; j < size; j++)
{
string word = S.substr(i + j * wordSize, wordSize);
if (wordCount.find(word) != wordCount.end())
{
counting[word]++;
if (counting[word] > wordCount[word])
break;
}
else break;
}
if (j == size)
result.push_back(i);
}
return result;
}
};
第十二题:
Balanced Binary Tree
分析:AVL树,递归写不好,脑残=。=
代码:
class Solution
{
private:
bool balanced;
int height(TreeNode *root)
{
if (!balanced) return -1;
if (root == NULL) return 0;
int leftD = height(root->left) + 1;
int rightD = height(root->right) + 1;
if (abs(leftD - rightD) > 1) balanced = false;
return leftD > rightD ? leftD : rightD;
}
public:
bool isBalanced(TreeNode *root)
{
balanced = true;
height(root);
return balanced;
}
};
第十三题:
Roman to Integer
分析:写的很逗比==改天重写一下,太长了,没用函数==
代码:
class Solution
{
public:
int romanToInt(string s)
{
int ans = 0;
int len = s.length();
int i = 0, j;
if (len == 0) return 0;
if (s[i] == 'M')
{
for (i = 0; i < len; i++)
{
if (s[i] != 'M') break;
}
ans += 1000 * i;
}
if (i == len) return ans;
if (s[i] == 'C')
{
j = i;
for (; i < len; i++)
{
if (s[i] != 'C') break;
}
if (i == len) return ans + 100 * (i - j);
if (s[i] == 'D')
{
ans += 400, i++;
}
else if (s[i] == 'M')
ans += 900, i++;
else ans += 100 * (i - j);
}
if (i == len) return ans;
if (s[i] == 'D') //DCXXI
{
i++;
ans += 500;
if (i == len) return ans;
if (s[i] == 'C')
{
j = i;
for ( ; i < len; i++)
{
if (s[i] != 'C') break;
}
ans += 100 * (i - j);
}
}
if (i == len) return ans;
if (s[i] == 'X')
{
j = i;
for (; i < len; i++)
if (s[i] != 'X') break;
if (i == len) return ans + 10 * (i - j);
if (s[i] == 'L') ans += 40, i++;
else if (s[i] == 'C') ans += 90, i++;
else ans += 10 * (i - j);
}
if (i == len) return ans;
if (s[i] == 'L')
{
i++;
ans += 50;
if (i == len) return ans;
if (s[i] == 'X')
{
j = i;
for ( ; i < len; i++)
if (s[i] != 'X') break;
ans += 10 * (i - j);
}
}
if (i == len) return ans;
if (s[i] == 'I')
{
j = i;
for ( ; i < len; i++)
if (s[i] != 'I') break;
if (i == len) return ans + (i - j);
if (s[i] == 'V') ans += 4, i++;
else if (s[i] == 'X') ans += 9, i++;
else ans += (i - j);
}
if (i == len) return ans;
if (s[i] == 'V')
{
i++;
ans += 5;
if (i == len) return ans;
if (s[i] == 'I')
{
j = i;
for ( ; i < len; i++)
if (s[i] != 'I') break;
ans += (i - j);
}
}
return ans;
}
};
第十四题:
Multiply Strings
分析:貌似是个水题吧=_=#!, 注意0的情况。 还有TLE(循环时为num1*num2,不要用定值,比如100000啥的。)
代码;
class Solution
{
public:
string multiply(string num1, string num2)
{
string ret = "";
int ans[100100];
int len1, len2;
int i, j, k = 0;
memset(ans, 0, sizeof(ans));
len1 = num1.length(), len2 = num2.length();
for (i = len1 - 1; i >= 0; i--)
{
k = len1 - i - 1;
for (j = len2 - 1; j >= 0; j--)
{
ans[k] += (num1[i] - '0') * (num2[j] - '0');
ans[k+1] += ans[k] / 10;
ans[k] %= 10;
k++;
}
}
for (i = 0; i < 100100-1; i++)
{
ans[i+1] += ans[i] / 10;
ans[i] %= 10;
}
for (i = 100100-1; i >= 0; i--)
if (ans[i] != 0) break;
for (; i >= 0; i--)
ret += char(ans[i]+'0');
return ret;
}
};
第十五题:
Implement strStr()
分析:最基本的KMP
代码:
class Solution
{
private:
int next[101000];
void getNext(char *needle)
{
int j, k, len = strlen(needle);
memset(next, 0, sizeof(next));
next[0] = -1;
j = 0, k = -1;
while (j < len-1)
{
if (k == -1 || needle[j] == needle[k]) j++, k++, next[j] = k;
else k = next[k];
}
}
int match(char *s, char *p)
{
int i, j, len;
getNext(p);
i = j = 0;
len = strlen(s);
while (i < len)
{
if (j == -1 || s[i] == p[j]) i++, j++;
else j = next[j];
if (j == strlen(p))
return i - strlen(p);
}
return -1;
}
public:
char *strStr(char *haystack, char *needle)
{
int ret;
if (strlen(needle) == 0) return haystack;
ret = match(haystack, needle);
if (ret == -1) return NULL;
return haystack + ret;
}
};
第十六题:
Plus One
分析:注意几个特殊情况即可。比如 负数的时候,进位。
class Solution
{
private:
void work(vector<int> &ans, int val)
{
int size = ans.size();
int i;
ans[size-1] += val;
for (i = size-1; i > 0; i--)
{
if (ans[i] < 0) ans[i-1] -= 1, ans[i] += 10;
ans[i-1] += ans[i] / 10;
ans[i] %= 10;
}
}
public:
vector<int> plusOne(vector<int> &digits)
{
int size = digits.size();
int i, j, flag;
vector<int> ans;
ans.push_back(0);
flag = 0;
if (digits[0] < 0) flag = 1;
for (i = 0; i < size; i++)
ans.push_back(abs(digits[i]));
if (flag == 0) work(ans, 1);
else work(ans, -1);
vector<int> ret;
ret.clear();
i = 0;
size = ans.size();
while (i != size && ans[i] == 0) i++;
if (i == size) { ret.push_back(0); return ret; }
if (flag) ret.push_back(-1 * ans[i++]);
while (i < size) ret.push_back(ans[i++]);
return ret;
}
};
第十七题:
Same Tree
分析:暴力。。brute force!!!
代码:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution
{
private:
bool ret;
void work(TreeNode *a, TreeNode *b)
{
if (a == NULL && b == NULL)
return ;
if ((a == NULL && b != NULL ) || (a != NULL && b == NULL)) { ret = false; return ; }
if (a->val != b->val) { ret = false; return ; }
if (a->left != NULL && a->left != NULL && b->left != NULL && b->right != NULL)
{
work(a->left, b->left);
work(a->right, b->right);
}
else if (a->left != NULL && a->right == NULL && b->left != NULL && b->right == NULL)
work(a->left, b->left);
else if (a->left == NULL && a->right != NULL && b->left == NULL && b->right != NULL)
work(a->right, b->right);
else if (a->left == NULL && a->right == NULL && b->left == NULL && b->right == NULL)
return ;
else { ret = false; return ;}
}
public:
bool isSameTree(TreeNode *p, TreeNode *q)
{
ret = true;
work(p, q);
return ret;
}
};
第十八题:
N-Queens II
分析:测试数据很小==直接暴力一下打表。
代码:
class Solution:
# @return an integer
def totalNQueens(self, n):
ans = [0, 1, 0, 0, 2, 10, 4, 40, 92, 352, 724, 2680, 14200]
return ans[n]
第十九题:
Pow(x, n)
分析:递归递归递归,注意负值以及极值的考虑。。。
代码:
class Solution
{
private:
double work(double x, int n)
{
double ret;
if (n == 0) return 1.0;
if (n == 1) return x;
if (n % 2 == 0)
{
ret = work(x, n/2);
return ret*ret;
}
else return x * work(x, n-1);
}
public:
double pow(double x, int n)
{
if (x == 0) return 0;
if (n < 0)
{
x = 1.0 / x;
if (n == -2147483648)
{
return work(x, -(n/2)) * work(x, -(n/2));
}
else n = -n;
}
return work(x, n);
}
};
第二十题:
Permutations II
分析:DFS,然后去重
代码:
class Solution
{
private:
bool canUse[100];
int a[100];
vector<vector<int> > ret;
public:
void dfs(int dep, int maxDep, vector<int> &num)
{
if (dep == maxDep)
{
vector<int> ans;
for(int i = 0; i < maxDep; i++)
ans.push_back(a[i]);
ret.push_back(ans);
return;
}
for(int i = 0; i < maxDep; i++)
if (canUse[i])
{
if (i != 0 && num[i] == num[i-1] && canUse[i-1])
continue;
canUse[i] = false;
a[dep] = num[i];
dfs(dep + 1, maxDep, num);
canUse[i] = true;
}
}
vector<vector<int> > permuteUnique(vector<int> &num)
{
sort(num.begin(), num.end());
memset(canUse, true, sizeof(canUse));
ret.clear();
dfs(0, num.size(), num);
return ret;
}
};