第一题:
Permutations
分析:全排列问题,DFS即可。
代码:
vector<int> visit;
int size;
vector<vector<int>> ans;
vector<int> add;
void dfs(int pos, vector<int> &num)
{
int i;
if (pos == size)
{
ans.push_back(add);
return ;
}
for (i = 0; i < size; i++)
{
if (visit[i] == 0)
{
visit[i] = 1;
add.push_back(num[i]);
dfs(pos+1, num);
visit[i] = 0;
add.pop_back();
}
}
}
class Solution
{
public:
vector<vector<int> > permute(vector<int> &num)
{
int i;
ans.clear();
add.clear();
size = num.size();
if (size == 0) return ans;
for (i = 0; i < size; i++) visit.push_back(0);
dfs(0, num);
return ans;
}
};
第二题:
Length of Last Word
分析:水题。
代码:
class Solution
{
public:
int lengthOfLastWord(const char *s)
{
int i, ans = 0, l1, flag;
l1 = strlen(s);
i = l1-1;
while (s[i] == ' ') i--;
for ( ; i >= 0; i--)
{
if (s[i] != ' ') ans += 1;
else break;
}
return ans;
}
};
第三题:
Linked List Cycle
分析:设置两个指针,一个跑得快,一个跑得慢。
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution
{
public:
bool hasCycle(ListNode *head)
{
ListNode* slow = head;
ListNode* fast = head;
while (fast != NULL && fast->next != NULL)
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast) return true;
}
return false;
}
};
第四题:
Maximal Rectangle
分析:和以前
Largest Rectangle in Histogram
题目处理方法一样,所以复杂度是O(mn),对每一行进行处理。代码:
int work(vector<int> &height)
{
stack<int> s;
int n = height.size();
int max_are = 0;
int tp, are_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();
are_with_top = height[tp] * (s.empty() ? i : i-s.top()-1);
if (max_are < are_with_top) max_are = are_with_top;
}
}
while (s.empty() == false)
{
tp = s.top();
s.pop();
are_with_top = height[tp] * (s.empty() ? i : i-s.top()-1);
if (max_are < are_with_top) max_are = are_with_top;
}
return max_are;
}
class Solution
{
public:
int maximalRectangle(vector<vector<char> > &matrix)
{
int size1, size2, i, j;
vector<vector<int>> dp;
vector<int> add;
add.clear();
dp.clear();
size1 = matrix.size();
if (size1 == 0) return 0;
size2 = matrix[0].size();
for (i = 0; i < size1; i++)
{
add.clear();
for (j = 0; j < size2; j++)
add.push_back(0);
dp.push_back(add);
}
for (i = 0; i < size2; i++) dp[0][i] = matrix[0][i] == '1' ? 1 : 0;
for (i = 1; i < size1; i++)
{
for (j = 0; j < size2; j++)
{
if (matrix[i][j] == '1') dp[i][j] = dp[i-1][j]+1;
else dp[i][j] = 0;
}
}
vector<int> height;
int ans = 0, ret;
for (i = 0; i < size1; i++)
{
height.clear();
for (j = 0; j < size2; j++) height.push_back(dp[i][j]);
ret = work(height);
if (ret > ans) ans = ret;
}
return ans;
}
};
第五题:
Linked List Cycle II
分析:如 Linked List Cycle I
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution
{
public:
ListNode *detectCycle(ListNode *head)
{
ListNode* slow = head;
ListNode* fast = head;
while (fast != NULL && fast->next != NULL)
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
{
slow = head;
while (slow != fast)
{
slow = slow->next;
fast = fast->next;
}
return slow;
}
}
return NULL;
}
};;
第六题:
Longest Common Prefix
分析:一开始想错了,其实比较简单吧。
代码:
class Solution
{
public:
string longestCommonPrefix(vector<string> &strs)
{
string result;
int len = strs.size();
int i,j;
if (len == 0)return "";
for (j = 0; ; ++j)
{
for (i = 0;i < len; ++i)
if (j >= strs[i].length() || strs[i][j] != strs[0][j]) break;
if (i < len) break;
result += strs[0][j];
}
return result;
}
};
第七题:
Binary Tree Maximum Path Sum
分析:一开始读错题了,看成必须是从叶子开始,到叶子结束。应该是从任意一个节点开始就可以==。好囧Orz。。。 动态规划。
代码:
int MAX(int a, int b) { return a > b ? a : b;}
int maxnum;
void dfs(TreeNode *root)
{
int a, b;
if (root == NULL) return;
dfs(root->left);
dfs(root->right);
if (root->left != NULL) a = root->left->val;
else a = 0;
if (root->right != NULL) b = root->right->val;
else b = 0;
if (root->val + a + b > maxnum) maxnum = root->val + a + b;
if (root->val > maxnum) maxnum = root->val;
if (a > 0 || b > 0) root->val += MAX(a, b);
if (root->val > maxnum) maxnum = root->val;
}
class Solution
{
public:
int maxPathSum(TreeNode *root)
{
maxnum = -100000000;
dfs(root);
return maxnum;
}
};
第八题:
Best Time to Buy and Sell Stock
分析:逗比了。理解错题意了。只买卖一次 =-=。 O(n)的复杂度。
代码:
int dp[101000];
class Solution
{
public:
int maxProfit(vector<int> &prices)
{
int i, j, size, maxnum, ans = 0;
memset(dp, 0, sizeof(dp));
size = prices.size();
if (size == 0) return 0;
maxnum = size-1;
dp[size-1] = prices[size-1];
for (i = size-2; i >= 0; i--)
{
if (prices[i] > prices[maxnum]) maxnum = i;
dp[i] = maxnum;
}
maxnum = 0;
for (i = 0; i < size-1; i++)
{
if (prices[i] >= prices[i+1] && i+1 < size) continue;
ans = prices[dp[i]]-prices[i];
if (ans > maxnum) maxnum = ans;
}
return maxnum;
}
};
第九题:
Best Time to Buy and Sell Stock II
分析:贪心。
代码:
class Solution
{
public:
int maxProfit(vector<int> &prices)
{
int ans = 0, size = prices.size(), i;
for (i = 1; i < size; i++)
ans += prices[i]-prices[i-1] > 0 ? prices[i]-prices[i-1] : 0;
return ans;
}
};
第十题:
Best Time to Buy and Sell Stock III
分析:动态规划,可以参考上面第八题,开两个数组,一个用于正向DP,一个用于逆向DP,然后扫描一遍就OK了。O(n)复杂度。
代码:
int dp1[50000];
int dp2[50000];
class Solution
{
public:
int maxProfit(vector<int> &prices)
{
int i, size;
int minnum, maxnum, bestans;
minnum = 100000000, maxnum = 0, bestans = 0;
size = prices.size();
if (size <= 1) return 0;
for (i = 0; i < size; i++)
{
if (prices[i] < minnum)
{
minnum = prices[i];
maxnum = 0;
}
if (prices[i] > maxnum)
{
maxnum = prices[i];
if (maxnum - minnum > bestans) bestans = maxnum-minnum;
}
dp1[i] = bestans;
}
maxnum = 0, minnum = 100000000, bestans = 0;
for (i = size-1; i >= 0; i--)
{
if (prices[i] > maxnum)
{
maxnum = prices[i];
minnum = 100000000;
}
if (prices[i] < minnum)
{
minnum = prices[i];
if (maxnum - minnum > bestans) bestans = maxnum - minnum;
}
dp2[i] = bestans;
}
bestans = 0;
for (i = 0; i < size; i++)
{
if (dp1[i] + dp2[i] > bestans) bestans = dp1[i]+dp2[i];
}
return bestans;
}
};
第十一题:
Linked List Cycle
分析:两个指针,一个一次走一步,另一个一次走两步。如果有环的话,肯定能够相遇的。没有的话。。。
代码:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# @param head, a ListNode
# @return a boolean
def hasCycle(self, head):
a = head
b = head
if head == None:
return False
while True:
if a.next == None or a.next.next == None:
return False
a = a.next.next
b = b.next
if a == b:
return True
第十二题:
Search in Rotated Sorted Array
分析:数组是排序然后旋转的,所以利用二分可以实现O(logn)
如果A[mid] > A[left] 那么mid左边一定是有序的,同理判断右。如果无序的话,那么无非就是先升后降,或者先降后升,然后判断一下即可。
class Solution:
# @param A, a list of integers
# @param target, an integer to be searched
# @return an integer
@staticmethod
def gao(A, left, right, target):
while left <= right:
mid = (left + right) // 2
if target == A[mid]: return mid
if A[mid] > A[left] and target >= A[left] and target <= A[mid]:
right = mid - 1
elif A[mid] < A[right] and target >= A[mid] and target <= A[right]:
left = mid + 1
elif (A[mid] > target or A[left] <= target) and A[mid] < A[left]:
right = mid-1
else: left = mid + 1
return -1
def search(self, A, target):
return Solution.gao(A, 0, len(A)-1, target)
第十三题:
Container With Most Water
分析:有n个高度不同的木板,他们之间的相邻距离为1,让你求用这些木板最多能够盛多少水。
贪心问题。 两个指针,一个指向头pi,一个指向尾pj,如果height[pi] < height[pj], 可以分析,这已经是利用pi为边界来盛水的容量极限了。
所以就将pi指针向右移。如此即可。
class Solution:
# @return an integer
def maxArea(self, height):
ans = 0
width, i, j = [len(height) - 1, len(height) - 1, 0]
while j < i:
ans = max(min(height[i], height[j]) * width , ans)
width -= 1
if height[i] > height[j]:
j += 1
else:
i -= 1
return ans
第十四题:
Unique Binary Search Trees
分析:直接套公式 (2n)!/(n+1)!/n!,结果要求是int,用地板除搞一下。不过貌似不用地板除也没问题。。。
代码:
class Solution:
# @return an integer
@staticmethod
def gao(a, b):
ans = 1
while a <= b:
ans = ans * a
a += 1
return ans
def numTrees(self, n):
if n < 2: return n
ans = Solution.gao(n+2, 2*n) // Solution.gao(1, n)
return ans
第十五题:
Insertion Sort List
分析:链表的基本操作,硬伤。。。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# @param head, a ListNode
# @return a ListNode
def insertionSortList(self, head):
if head == None: return None
go = ListNode(0)
ans = ListNode(0)
ans.next = go
go.__init__(head.val)
last = head.val
it = head.next
while it != None:
aa = ans.next
pre = ans
if it.val < last:
while aa != None:
if aa.val > it.val:
break
pre = aa
aa = aa.next
pre.next = it
it = it.next
pre.next.next = aa
else:
last = it.val
go.next = it
it = it.next
go.next.next = None
go = go.next
return ans.next
第十六题:
First Missing Positive
分析:
交换数组元素,使得数组中第i位存放数值(i+1)。最后遍历数组,寻找第一个不符合此要求的元素,返回其下标。整个过程需要遍历两次数组,复杂度为O(n)。
PS: 写过一次,但是那个是错误的=。=用了非常数大小的内存。。。所以以前那个不对。
代码:
class Solution:
# @param A, a list of integers
# @return an integer
def firstMissingPositive(self, A):
i = 0
while i < len(A):
if A[i] != (i+1) and A[i] >= 1 and A[i] <= len(A) and A[A[i]-1] != A[i]:
temp = A[i]
A[i] = A[A[i]-1]
A[temp-1] = temp
else:
i += 1
i = 0
for i in range(len(A)):
if A[i] != i+1:
return i+1
return len(A)+1
第十七题:
Sum Root to Leaf Numbers
分析: DFS一下即可。一开始忘记每次都要初始化ans了。。然后WA了一发。
代码:
# Definition for a binary tree node
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
# @param root, a tree node
# @return an integer
ans = 0
@staticmethod
def dfs(root, cc):
cc = cc + root.val
if root.left == None and root.right == None:
Solution.ans = Solution.ans + cc
return
if root.left != None:
Solution.dfs(root.left, 10*cc)
if root.right != None:
Solution.dfs(root.right, 10*cc)
def sumNumbers(self, root):
if root == None:
return 0
Solution.ans = 0
Solution.dfs(root, 0)
return Solution.ans
第十八题:
Set Matrix Zeroes
分析:要求把matrix中的0所在的行以及列全部元素置为0,并且原地操作。只能使用常数内存。
我们可以用matrix 的第0行以及第0列来表示matrix中的0的位置。
比如matrix[4][3]处为0,那么matrix[4][0]即为0,matrix[0][3]也为0.
这样有另一个问题,即第0行以及第0列的存在的0如何表示,我们用flag1以及flag2两个标记。来分别
表示第0行存在0,或者第0列存在0.然后扫描一下matrix即可。
class Solution:
# @param matrix, a list of lists of integers
# RETURN NOTHING, MODIFY matrix IN PLACE.
def setZeroes(self, matrix):
m, n = [len(matrix), len(matrix[0])]
flag1, flag2 = [0, 0]
for i in range(m):
for j in range(n):
if matrix[i][j] == 0:
if i == 0 and j == 0:
flag1 = 1
flag2 = 1
elif i == 0:
flag1 = 1
matrix[0][j] = 0
elif j == 0:
flag2 = 1
matrix[i][0]
else:
matrix[i][0] = 0
matrix[0][j] = 0
i = 1
while i < n:
if matrix[0][i] == 0:
for j in range(m):
matrix[j][i] = 0
i = i + 1
i = 0
while i < m:
if matrix[i][0] == 0:
for j in range(n):
matrix[i][j] = 0
i = i + 1
if flag1 == 1:
for j in range(n):
matrix[0][j] = 0
if flag2 == 1:
for j in range(m):
matrix[j][0] = 0
第十九题:
Restore IP Addresses
分析:一字符串判断是否为合法IP地址,若合法,就转化。
注意的问题:
①、 如果串长度大于12,肯定不是。
②、a.b.c.d 每个数字的取值范围是 0~255
③、 0.01.0.0 这不是合法的,因为在第二个是01即若数字的长度大于1且第一位为0,,则不合法。
代码:
class Solution:
# @param s, a string
# @return a list of strings
@staticmethod
def judge(i, j, k, s):
a, b, c, d = [0, 0, 0, 0]
for m in range(i+1):
a = a*10 + int(s[m])
if s[0] == '0' and i > 0: a = 299
for m in range(i+1, j+1):
b = b*10 + int(s[m])
if s[i+1] == '0' and (j-i) > 1: b = 299
for m in range(j+1, k+1):
c = c*10 + int(s[m])
if s[j+1] == '0' and (k-j) > 1: c = 299
for m in range(k+1, len(s)):
d = d*10 + int(s[m])
if s[k+1] == '0' and (len(s)-k-1) > 1: d = 299#
if a >= 0 and a <= 255 and b >= 0 and b <= 255 and c >= 0 and c <= 255 and d >= 0 and d <= 255:
ret = str(a) + '.' + str(b) + '.' + str(c) + '.' + str(d)
return ret
return '-'
def restoreIpAddresses(self, s):
ans = []
if len(s) > 12: return ans
for i in range(len(s)-3):
for j in range(i+1, len(s)-2):
for k in range(j+1, len(s)-1):
ret = Solution.judge(i, j, k, s)
if ret != '-':
ans.append(ret)
return ans
第二十题:
Search Insert Position
分析:二分。如果没有则返回left的值,此时left即为大于target 的第一个数的index
代码:
class Solution:
# @param A, a list of integers
# @param target, an integer to be inserted
# @return integer
@staticmethod
def binary_search(A, target):
left, right = [0, len(A)-1]
while left <= right:
mid = (left + right) // 2
if A[mid] == target:
return mid
elif A[mid] < target:
left = mid + 1
else:
right = mid - 1
return left
def searchInsert(self, A, target):
return Solution.binary_search(A, target)