01 2015 档案

摘要:原题地址跟2Sum、3Sum、4Sum类似,都是:排序+搜索+剪枝令sum = num[i] + num[j] + num[k] + (-target)(将-target看做一个必选的数),那这道题就跟4Sum(参见这篇文章)几乎一样了,变成了寻找最接近0的和。需要剪枝的地方:1. 数字太小,肯定不... 阅读全文
posted @ 2015-01-30 20:32 李舜阳 阅读(199) 评论(0) 推荐(0) 编辑
摘要:原题地址BFSWord Ladder II的简化版(参见这篇文章)由于只需要计算步数,所以简单许多。代码: 1 int ladderLength(string start, string end, unordered_set &dict) { 2 if (start == end) ... 阅读全文
posted @ 2015-01-30 18:39 李舜阳 阅读(151) 评论(0) 推荐(0) 编辑
摘要:原题地址基本链表操作代码: 1 ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) { 2 ListNode *h = NULL; 3 ListNode *t = NULL; 4 int carry ... 阅读全文
posted @ 2015-01-30 17:28 李舜阳 阅读(164) 评论(0) 推荐(0) 编辑
摘要:原题地址标准DFS+剪枝。将数字提前排序,一来方便去重,二来创造剪枝条件。1. 如果当前数字过大,就算加上最小的数字最后都超过target,停止继续尝试之后的数字,因为后面的数字更大2. 如果当前数字过小,就算加上后面最大的数字最后都不到target,不用再考虑这个数字了,继续尝试后面更大的数字3.... 阅读全文
posted @ 2015-01-30 17:20 李舜阳 阅读(249) 评论(0) 推荐(0) 编辑
摘要:原题地址简单DFS题目代码: 1 vector res; 2 3 void dfs(string &digits, vector &i2s, string ans, int pos) { 4 if (pos == digits.length()) { 5 res.push_ba... 阅读全文
posted @ 2015-01-30 15:42 李舜阳 阅读(137) 评论(0) 推荐(0) 编辑
摘要:原题地址如果不限交易次数,把所有递增序列差值求和即可。代码: 1 int maxProfit(vector &prices) { 2 if (prices.empty()) 3 return 0; 4 5 int profi... 阅读全文
posted @ 2015-01-30 15:34 李舜阳 阅读(171) 评论(0) 推荐(0) 编辑
摘要:原题地址Best Time to Buy and Sell Stock III(参见这篇文章)的简化版迭代法求最大利润。当然是在峰值卖出,在低谷买进利润最大了。所以从后向前遍历所有价格,如果当前价格比之前的峰值价格还高,更新峰值价格,否则就用峰值价格减去当前价格看看利润多少。代码: 1 int ma... 阅读全文
posted @ 2015-01-30 15:26 李舜阳 阅读(121) 评论(0) 推荐(0) 编辑
摘要:原题地址数字三角,经典动归题。编码时可状态压缩成1维数组代码: 1 int minimumTotal(vector > &triangle) { 2 if (triangle.empty()) return -1; 3 4 vector layer(... 阅读全文
posted @ 2015-01-30 15:21 李舜阳 阅读(115) 评论(0) 推荐(0) 编辑
摘要:原题地址最初的想法是用动态规划,令palin[i][j]表示s[i..j]是否是回文串,则有递推公式palin[i][j] = s[i] == s[j] && palin[i+1][j-1]。因为递推式只使用相邻层的值,所以编码的时候可以将二维状态数组压缩成一维的。代码: 1 string long... 阅读全文
posted @ 2015-01-30 15:02 李舜阳 阅读(206) 评论(0) 推荐(0) 编辑
摘要:原题地址Populating Next Right Pointers in Each Node II(参见这篇文章)的简化版,代码不变代码: 1 void connect(TreeLinkNode *root) { 2 queue layer; 3 4 layer.push(root); ... 阅读全文
posted @ 2015-01-30 14:18 李舜阳 阅读(151) 评论(0) 推荐(0) 编辑
摘要:原题地址计算循环小数先把负数转化成正数,然后计算,最后添加符号当被除数重复出现的时候,说明开始循环了,所以用一个map保存所有遇到的被除数需要考虑溢出问题,这也是本题最恶心的地方,看看通过率吧,比Hard难度的题还低。最残暴的做法是直接转成64位长整型,比如下面的代码。好处是代码简洁了许多,不过这是... 阅读全文
posted @ 2015-01-30 13:06 李舜阳 阅读(345) 评论(0) 推荐(0) 编辑
摘要:原题地址先序遍历二叉树,递归展开。别忘了将left设为NULL,如果忘掉的话可能报Runtime Error,而且这个RE很难查出原因。代码: 1 TreeNode *solve(TreeNode *root) { 2 if (!root) return NULL; 3 4 ... 阅读全文
posted @ 2015-01-30 10:54 李舜阳 阅读(158) 评论(0) 推荐(0) 编辑
摘要:原题地址二叉树基本操作——遍历题目没说数字都是正数,所以没法剪枝,只能全部遍历一遍。代码: 1 vector > res; 2 3 void traverse(TreeNode *root, vector ans, int sum) { 4 if (!root) 5 retur... 阅读全文
posted @ 2015-01-30 10:30 李舜阳 阅读(132) 评论(0) 推荐(0) 编辑
摘要:原题地址简化版本的Find Minimum in Rotated Sorted Array II(参见这篇文章)二分查找最小值,每次只需要查看其中一个二分区间即可。如果A[i] A[j]则说明A[i..j]肯定是非连续的,说明最小值肯定出现在A[i..j]中当中,之后继续在这一半内查找,另一半可以... 阅读全文
posted @ 2015-01-30 10:16 李舜阳 阅读(114) 评论(0) 推荐(0) 编辑
摘要:原题地址简单动态规划,跟最大子串和类似。一维状态空间可以经过压缩变成常数空间。代码: 1 int maxProduct(int A[], int n) { 2 if (n = 0; i--) {10 int tmp = minp;11 ... 阅读全文
posted @ 2015-01-30 09:57 李舜阳 阅读(141) 评论(0) 推荐(0) 编辑
摘要:原题地址跟Convert Sorted Array to Binary Search Tree(参见这篇文章)类似,只不过用list就不能随机访问了。代码: 1 TreeNode *buildBST(ListNode *head, int len) { 2 if (len next; 9 ... 阅读全文
posted @ 2015-01-30 09:48 李舜阳 阅读(143) 评论(0) 推荐(0) 编辑
摘要:原题地址对于已排序数组,二分法递归构造BST代码: 1 TreeNode *buildBST(vector &num, int i, int j) { 2 if (i > j) 3 return NULL; 4 5 int m = (i + j) /2; 6 T... 阅读全文
posted @ 2015-01-30 09:31 李舜阳 阅读(493) 评论(0) 推荐(0) 编辑
摘要:原题地址将单词按空格分词,然后倒序拼接即可代码: 1 void reverseWords(string &s) { 2 vector words; 3 4 int start = -1; 5 int len = 0; 6 ... 阅读全文
posted @ 2015-01-30 09:26 李舜阳 阅读(185) 评论(0) 推荐(0) 编辑
摘要:原题地址二叉树基本操作[ ]O[ ][ ][ ]O代码: 1 TreeNode *restore(vector &inorder, vector &postorder, int ip, int pp, int len) { 2 if (len == 0) 3 ... 阅读全文
posted @ 2015-01-30 09:11 李舜阳 阅读(141) 评论(0) 推荐(0) 编辑
摘要:原题地址基本二叉树操作。O[ ][ ][ ]O[ ]代码: 1 TreeNode *restore(vector &preorder, vector &inorder, int pp, int ip, int len) { 2 if (len left = r... 阅读全文
posted @ 2015-01-30 09:02 李舜阳 阅读(125) 评论(0) 推荐(0) 编辑
摘要:原题地址链表归并排序真是恶心的一道题啊,哇了好多次才过。代码: 1 void mergeList(ListNode *a, ListNode *b, ListNode *&h, ListNode *&t) { 2 h = t = NULL; 3 while (a && b) { 4 ... 阅读全文
posted @ 2015-01-29 20:22 李舜阳 阅读(108) 评论(0) 推荐(0) 编辑
摘要:原题地址基本栈操作。注意数字有可能是负的。代码: 1 int toInteger(string &s) { 2 int res = 0; 3 bool negative = s[0] == '-' ? true : false; 4 5 for (int i = neg... 阅读全文
posted @ 2015-01-29 19:06 李舜阳 阅读(135) 评论(0) 推荐(0) 编辑
摘要:原题地址基本数据结构操作,二叉树的层次遍历。代码: 1 vector > zigzagLevelOrder(TreeNode *root) { 2 vector > res; 3 vector layer; 4 bool l2r = true; 5 ... 阅读全文
posted @ 2015-01-29 18:52 李舜阳 阅读(121) 评论(0) 推荐(0) 编辑
摘要:原题地址双指针法。右指针不断向右试探,当遇到重复字符时停下来,此时左指针开始向右收缩,直到去掉那个重复字符。代码: 1 int lengthOfLongestSubstring(string s) { 2 map record; 3 int maxLen = 0; 4... 阅读全文
posted @ 2015-01-29 18:33 李舜阳 阅读(183) 评论(0) 推荐(0) 编辑
摘要:原题地址Unique Binary Search Trees(参见这篇文章)的升级版做题的时候我在想,这要是把每个二叉树都独立创建一份得多麻烦啊,试试能不能共用"公共部分",试了一下,果然可以,哈哈。trees[i][j]表示数字i到j所能组成的所有二叉树的根节点代码: 1 vector gener... 阅读全文
posted @ 2015-01-29 17:48 李舜阳 阅读(368) 评论(0) 推荐(0) 编辑
摘要:原题地址心得:做链表类题目,多用中间变量,代码的可读性比简洁性更重要,适当注释。在纸上画画图,看看各操作节点的next指针最后都指对了没。代码: 1 ListNode *swapPairs(ListNode *head) { 2 if (!head) 3 r... 阅读全文
posted @ 2015-01-29 17:40 李舜阳 阅读(158) 评论(0) 推荐(0) 编辑
摘要:原题地址心得:有关链表的题目,多用中间变量,代码写得清晰一点,适当注释代码: 1 ListNode *insertionSortList(ListNode *head) { 2 if (!head) return NULL; 3 4 ListNode... 阅读全文
posted @ 2015-01-29 17:28 李舜阳 阅读(175) 评论(0) 推荐(0) 编辑
摘要:原题地址中序遍历二叉树,如果出现逆序对,则说明不是合法BST代码: 1 bool isValidBST(TreeNode *root) { 2 stack st; 3 int last = 0; 4 bool hasLast = false; 5 ... 阅读全文
posted @ 2015-01-29 17:11 李舜阳 阅读(121) 评论(0) 推荐(0) 编辑
摘要:原题地址动态规划,根据二叉树的根节点将原问题划分为两个子问题。代码: 1 int numTrees(int n) { 2 vector num(n + 1, 0); 3 4 num[0] = 1; 5 for (int i = 1; ... 阅读全文
posted @ 2015-01-29 15:07 李舜阳 阅读(196) 评论(0) 推荐(0) 编辑
摘要:原题地址考察非递归写法。前序遍历可以参考这篇文章,后序遍历可以参考这篇代码: 1 vector inorderTraversal(TreeNode *root) { 2 TreeNode *node = NULL; 3 stack st; 4 vect... 阅读全文
posted @ 2015-01-29 14:36 李舜阳 阅读(129) 评论(0) 推荐(0) 编辑
摘要:原题地址DFS注意以下几点:1. IP地址中间的数字范围是0~2552. IP地址中间的数字不能有前导0(0除外)3. 如果原IP串长度超过12就不用做了,直接返回空代码: 1 vector res; 2 3 void dfs(string &s, vector ans, int pos,... 阅读全文
posted @ 2015-01-29 14:28 李舜阳 阅读(165) 评论(0) 推荐(0) 编辑
摘要:原题地址第一步,找到将要翻转的位置,记录翻转部分前一个节点(prev)第二步,翻转,记录翻转完成后这部分的首(reverseHead)和尾(reverseTail),以及翻转部分之后的一个节点(post)第三部,将prev、reverseHead、reverseTail、post连接起来代码: 1 ... 阅读全文
posted @ 2015-01-29 14:00 李舜阳 阅读(156) 评论(0) 推荐(0) 编辑
摘要:原题地址跟Subsets(参见这篇文章)类似。但因为有重复元素,所以要考虑去重问题。什么情况下会出现重复呢?比如S = {5, 5, 5},如果要选1个5,一共有C(3,1)=3种选法,即100, 010, 001,这三种情况在集合的角度看是重复的情况。如果要选2个5,共有C(3,2)=3种选法,即... 阅读全文
posted @ 2015-01-29 12:21 李舜阳 阅读(198) 评论(0) 推荐(0) 编辑
摘要:原题地址动态规划题,注意0导致的小陷阱。代码: 1 int numDecodings(string s) { 2 if (s.empty() || s[0] '9') return 0; 3 4 int sum = s[s.length() - 1... 阅读全文
posted @ 2015-01-29 11:48 李舜阳 阅读(162) 评论(0) 推荐(0) 编辑
摘要:原题地址凡是涉及链表的题目,代码越清楚越好。代码: 1 ListNode *partition(ListNode *head, int x) { 2 ListNode *ltHead = NULL; 3 ListNode *ltTail = NULL; 4 ... 阅读全文
posted @ 2015-01-29 11:06 李舜阳 阅读(188) 评论(0) 推荐(0) 编辑
摘要:原题地址递归代码谁都会,当然是写非递归代码了。最基本的写法是用一个特殊栈同时保存节点以及节点的左孩子、右孩子是否遍历过。这种思路比较简单,跟递归写法一样很好理解。前序、中序、后序的遍历写法类似。还有一种更"屌"的写法,只需要使用普通栈即可,不需要保存左孩子、右孩子是否遍历过。基本思路是:1. 只要当... 阅读全文
posted @ 2015-01-29 10:51 李舜阳 阅读(262) 评论(0) 推荐(0) 编辑
摘要:原题地址不用除运算和模运算的除法就退化成最基本的减法如果除数是1,被除数超大,这做减法还不得累死,所以,用位运算加快速度。对于被除数和除数都是正数的情况,除法流程为:用位运算生成小于等于当前被除数一半的数字,然后一口气减掉,如此循环往复,直到被除数小于除数。对于其他被除数和除数当中有负数的情况,为了... 阅读全文
posted @ 2015-01-29 10:27 李舜阳 阅读(258) 评论(0) 推荐(0) 编辑
摘要:原题地址基本模拟题代码: 1 ListNode *deleteDuplicates(ListNode *head) { 2 if (!head) 3 return head; 4 5 ListNode *h = NUL... 阅读全文
posted @ 2015-01-29 09:10 李舜阳 阅读(126) 评论(0) 推荐(0) 编辑
摘要:原题地址先把链表分割成前后两半,然后交叉融合实践证明,凡是链表相关的题目,都应该当成工程类题目做,局部变量、功能函数什么的随便整,代码长了没关系,关键是清楚,不容易出错。代码: 1 ListNode *reverseList(ListNode *head) { 2 if (!head) retu... 阅读全文
posted @ 2015-01-28 21:23 李舜阳 阅读(172) 评论(0) 推荐(0) 编辑
摘要:原题地址如果不存在重复元素,仅通过判断数组的首尾元素即可判断数组是否连续,但是有重复元素的话就不行了,最坏情况下所有元素都一样,此时只能通过线性扫描确定是否连续。设对于规模为n的问题的工作量为T(n),则有T(n) = T(n/2) + O(n),根据主定理,可以求得T(n) = O(n)。和之前的... 阅读全文
posted @ 2015-01-28 19:55 李舜阳 阅读(116) 评论(0) 推荐(0) 编辑
摘要:原题地址简单模拟题。从先向后遍历,如果重复出现2次以上,就不移动,否则移动到前面去代码: 1 int removeDuplicates(int A[], int n) { 2 if (n == 0) return n; 3 4 int len = 1... 阅读全文
posted @ 2015-01-28 17:05 李舜阳 阅读(130) 评论(0) 推荐(0) 编辑
摘要:原题地址依次枚举起始点,DFS+回溯代码: 1 bool dfs(vector > &board, int r, int c, string word) { 2 int m = board.size(); 3 int n = board[0].size(); 4 int dir[4][2... 阅读全文
posted @ 2015-01-28 16:55 李舜阳 阅读(250) 评论(0) 推荐(0) 编辑
摘要:原题地址有两种方法:1. 对于序列S,其子集可以对应为一个二进制数,每一位对应集合中的某个数字,0代表不选,1代表选,比如S={1,2,3},则子集合就是3bit的所有二进制数。所以,照着二进制位去构造解空间即可。2. 也可以用DFS做,对于每个元素,要么选,要么不选。记得先排序,因为结果集的数字要... 阅读全文
posted @ 2015-01-28 16:26 李舜阳 阅读(169) 评论(0) 推荐(0) 编辑
摘要:原题地址生成字典序,交换 + 逆序生成字典序的方法:1. 从后向前,寻找第一个正序对,即num[i] &num) { 2 int i = num.size() - 2; 3 while (i >= 0 && num[i] >= num[i + 1]) 4 ... 阅读全文
posted @ 2015-01-28 15:49 李舜阳 阅读(517) 评论(0) 推荐(0) 编辑
摘要:原题地址w指针遍历数组,如果w跨过b,则退出若w指向的元素是白色,指针右移若w指向的元素是红色,交换w和r指向的元素若w指向的元素是蓝色,交换w和b指向的元素代码: 1 void sortColors(int A[], int n) { 2 int r = 0; 3 int w = 0; 4... 阅读全文
posted @ 2015-01-28 15:30 李舜阳 阅读(165) 评论(0) 推荐(0) 编辑
摘要:原题地址二分搜索变种先按行搜索,然后按列搜索代码: 1 bool searchMatrix(vector > &matrix, int target) { 2 if (matrix.empty() || matrix[0].empty()) return false; 3 4 int m ... 阅读全文
posted @ 2015-01-28 15:10 李舜阳 阅读(146) 评论(0) 推荐(0) 编辑
摘要:原题地址用矩形的第一行和第一列充当mask代码: 1 void setZeroes(vector > &matrix) { 2 if (matrix.empty() || matrix[0].empty()) return; 3 4 bool fir... 阅读全文
posted @ 2015-01-28 14:54 李舜阳 阅读(132) 评论(0) 推荐(0) 编辑
摘要:原题地址二分搜索变种代码: 1 vector searchRange(int A[], int n, int target) { 2 vector range(2, -1); 3 int l, r; 4 5 // left 6 ... 阅读全文
posted @ 2015-01-28 14:43 李舜阳 阅读(139) 评论(0) 推荐(0) 编辑
摘要:原题地址经典的链表题目。1. 用双指针法判断是否有环2. 将一个指针重置为链表首部,另一个指针保留在之前重合的位置,两个指针同时移动,相遇位置即为环出现的位置2的证明:设链表头节点是A,环出现位置为B,快慢指针最终相遇位置为C,如下图所示设环的周长为p,则有:1. 快指针所走的路径长度为 L_fas... 阅读全文
posted @ 2015-01-28 14:25 李舜阳 阅读(214) 评论(0) 推荐(0) 编辑
摘要:原题地址小心溢出。检测乘法溢出的方法:设乘数为A、B,乘积为C,检验C / A =? B,前提是B != 0检测加法溢出的方法:检验A + B <? 0代码: 1 int sqrt(int x) { 2 int l = 0; 3 int r = x; 4 5 while (l <= r... 阅读全文
posted @ 2015-01-28 13:55 李舜阳 阅读(127) 评论(0) 推荐(0) 编辑
摘要:原题地址二分搜索变种,注意到当左指针和右指针相交后,应该插入的位置总是在左指针处,所以直接返回左指针即可。代码: 1 int searchInsert(int A[], int n, int target) { 2 int l = 0; 3 int r = n - 1... 阅读全文
posted @ 2015-01-28 12:16 李舜阳 阅读(104) 评论(0) 推荐(0) 编辑
摘要:原题地址经典链表题目,快慢指针法。曾经是面试热门题目之一,现在有些过时了。代码: 1 bool hasCycle(ListNode *head) { 2 ListNode *fast = head; 3 ListNode *slow = head; 4 ... 阅读全文
posted @ 2015-01-28 12:08 李舜阳 阅读(127) 评论(0) 推荐(0) 编辑
摘要:原题地址最朴素的想法就是,枚举容器的左边界和右边界,总能找到解,不过时间复杂度是O(n^2)的。改进I:从左向右枚举左边界,在此基础上从右向左枚举右边界,一旦右边界高度>=左边界高度就可以停止枚举了,因为继续枚举下去找到的矩形肯定面积更小。比如下图,左边界在位置0,高度为height[0]=3,那么... 阅读全文
posted @ 2015-01-28 11:52 李舜阳 阅读(184) 评论(0) 推荐(0) 编辑
摘要:原题地址与Word Break II(参见这篇文章)相比,只需要判断是否可行,不需要构造解,简单一些。依然是动态规划。代码: 1 bool wordBreak(string s, unordered_set &dict) { 2 int maxLen = 0; 3 f... 阅读全文
posted @ 2015-01-28 11:01 李舜阳 阅读(143) 评论(0) 推荐(0) 编辑
摘要:原题地址找规律+模拟,真没啥可说的。代码: 1 string intToRoman(int num) { 2 string res; 3 4 while (num >= 1000) { 5 res += "M"; 6 ... 阅读全文
posted @ 2015-01-27 19:42 李舜阳 阅读(148) 评论(0) 推荐(0) 编辑
摘要:原题地址基本动态规划题代码: 1 int minPathSum(vector > &grid) { 2 if (grid.empty() || grid[0].empty()) return 0; 3 4 int m = grid.size(); 5 int n = grid[0].s... 阅读全文
posted @ 2015-01-27 18:50 李舜阳 阅读(151) 评论(0) 推荐(0) 编辑
摘要:原题地址基本动态规划题代码: 1 int uniquePathsWithObstacles(vector > &obstacleGrid) { 2 if (obstacleGrid.empty() || obstacleGrid[0].empty()) return 0; 3 ... 阅读全文
posted @ 2015-01-27 18:31 李舜阳 阅读(140) 评论(0) 推荐(0) 编辑
摘要:原题地址基本动态规划题代码: 1 int uniquePaths(int m, int n) { 2 vector sum(n, 0); 3 4 sum[n - 1] = 1; 5 for (int i = m - 1; i >= 0... 阅读全文
posted @ 2015-01-27 18:24 李舜阳 阅读(158) 评论(0) 推荐(0) 编辑
摘要:原题地址我一直不太理解为什么叫rotate,翻译成"旋转"吧,似乎也不像啊。比如:1->2->3->4->5->NULL向右旋转2的距离,变成了:4->5->1->2->3->NULL后来琢磨半天+跟人讨论,似乎可以这么理解"rotate"1. 循环shift。这个比较容易理解。2. 环旋转。意思是... 阅读全文
posted @ 2015-01-27 18:06 李舜阳 阅读(250) 评论(0) 推荐(0) 编辑
摘要:原题地址一个一个模拟肯定要超时,只有生算找规律呗。比如n=4,k=10,先将n=4的所有排列写出来:(1) 1 2 3 4(2) 1 2 4 3(3) 1 3 2 4(4) 1 3 4 2(5) 1 4 2 3(6) 1 4 3 2(7) 2 1 3 4(8) 2 1 4 3(9) ... 阅读全文
posted @ 2015-01-27 17:18 李舜阳 阅读(318) 评论(0) 推荐(0) 编辑
摘要:原题地址相比于Spiral Matrix(参见这篇文章)要简单一些,因为是方阵,所以代码简洁一些。注意当n是奇数的时候,中心小块要单独赋值(代码21行)代码: 1 vector > generateMatrix(int n) { 2 vector > matrix(n, vector(n, 0)... 阅读全文
posted @ 2015-01-27 15:32 李舜阳 阅读(150) 评论(0) 推荐(0) 编辑
摘要:原题地址经典题目。所有数字异或,剩下的就是只出现一次的数字,因为其他出现两次的数字都没啦。T ^ T = 0代码:1 int singleNumber(int A[], int n) {2 int res = 0;3 4 for (int i = 0; i < n; i++)5 re... 阅读全文
posted @ 2015-01-27 15:19 李舜阳 阅读(142) 评论(0) 推荐(0) 编辑
摘要:原题地址排序+DFS与Combination Sum II(参见这篇文章)不同的地方在于,重复的数字可以使用多次,无所谓啦,反正代码几乎都一样。代码: 1 vector > res; 2 3 void dfs(vector &candidates, vector ans, int pos, int... 阅读全文
posted @ 2015-01-27 15:16 李舜阳 阅读(143) 评论(0) 推荐(0) 编辑
摘要:原题地址跟Jump Game II(见这篇文章)不同的地方在于,只需要判断能否到达终点即可遍历每个位置,更新能够到达的范围,最后看看范围是否覆盖了终点代码: 1 bool canJump(int A[], int n) { 2 int range = 0; 3 int... 阅读全文
posted @ 2015-01-27 14:54 李舜阳 阅读(154) 评论(0) 推荐(0) 编辑
摘要:原题地址简单模拟,用t,b,l,r分别表示当前的上下左右四个边界,然后遍历即可代码: 1 vector spiralOrder(vector > &matrix) { 2 if (matrix.empty() || matrix[0].empty()) return vector(); 3 4... 阅读全文
posted @ 2015-01-27 14:43 李舜阳 阅读(259) 评论(0) 推荐(0) 编辑
摘要:原题地址方法I:动态规划另sum[i]表示从i开始的最大子串和,则有递推公式:sum[i] = max{A[i], A[i] + sum[i+1]}因为递推式只用到了后一项,所以在编码实现的时候可以进行状态压缩,用一个变量即可代码: 1 int maxSubArray(int A[], int n)... 阅读全文
posted @ 2015-01-27 14:02 李舜阳 阅读(2777) 评论(0) 推荐(0) 编辑
摘要:原题地址排序+DFS代码: 1 vector > res; 2 3 void dfs(vector &num, vector &ans, int pos, int left) { 4 if (left == 0) 5 res.push_back(ans); 6 for (i... 阅读全文
posted @ 2015-01-27 11:00 李舜阳 阅读(522) 评论(0) 推荐(0) 编辑
摘要:原题地址想当年初学C++的时候写个大整数加法都快屎了,现在觉得自己还是成长了不少哇。代码: 1 string multiply(string num1, string num2) { 2 int len1 = num1.length(); 3 int len2 = n... 阅读全文
posted @ 2015-01-27 02:27 李舜阳 阅读(149) 评论(0) 推荐(0) 编辑
摘要:原题地址普通分治题。需要注意n可正可负。代码: 1 double pow(double x, int n) { 2 if (n == 0) return 1; 3 if (n == 1) return x; 4 if (n == -1) return ... 阅读全文
posted @ 2015-01-27 02:12 李舜阳 阅读(139) 评论(0) 推荐(0) 编辑
摘要:原题地址Anagram:变位词。两个单词是变位词关系的条件是:组成单词的字符相同,只是顺序不同第一次看这道题看了半天没明白要干嘛,丫就不能给个样例输入输出么。。后来还是看网上其他人的总结知道是怎么回事。通常的做法是:把字符串内的字符排序,这样,凡是变位词都会变成相同的单词。用map记录这样的单词出现... 阅读全文
posted @ 2015-01-27 02:00 李舜阳 阅读(188) 评论(0) 推荐(0) 编辑
摘要:原题地址普遍的做法是:用栈保存从根节点到当前尚未遍历过的最小节点的路径(栈顶始终是最小节点)constructor:遍历至最小节点,同时将路径上出现的节点压栈保存hasNext:返回栈里面是否还有元素next:栈顶元素即为所求,弹栈的同时更新栈,使栈里始终保存的是从根节点到剩余未遍历节点的最小节点的... 阅读全文
posted @ 2015-01-27 01:49 李舜阳 阅读(543) 评论(0) 推荐(0) 编辑
摘要:原题地址按"."分割,然后比较需要注意的地方:1. 多于的前缀0。例如"001"="1"2. 多余的后缀版本号。例如"1"="1.0.0.0"代码: 1 int compareVersion(string version1, string version2) { 2 int last1 = -1... 阅读全文
posted @ 2015-01-26 21:16 李舜阳 阅读(139) 评论(0) 推荐(0) 编辑
摘要:原题地址寻找主元素非常巧妙的方法代码: 1 int majorityElement(vector &num) { 2 int candidate = 0; 3 int count = 0; 4 5 for (int i = 0; i < num.size(); i++)... 阅读全文
posted @ 2015-01-26 20:28 李舜阳 阅读(126) 评论(0) 推荐(0) 编辑
摘要:原题地址典型的地图寻路问题如何计算当前位置最少需要多少体力呢?无非就是在向下走或向右走两个方案里做出选择罢了。如果向下走,看看当前位置能提供多少体力(如果是恶魔就是负数,如果是草药就是正数),如果当前位置能够提供的体力比向下走所需要的最小体力还多,那么当前位置只需要1的体力就够了;否则,计算出额外需... 阅读全文
posted @ 2015-01-26 18:59 李舜阳 阅读(614) 评论(0) 推荐(0) 编辑
摘要:原题地址先将数字转成字符串,然后排序,让能够组成更大数字的字符串放在前面,最后拼接成完整的字符串即可。有种很巧妙的方法判断两个字符串的大小关系,假设两个字符串是A,B,则比较AB和BA,若AB比BA大,说明A应该放在前面,即A &num) { 2 string res; 3 ... 阅读全文
posted @ 2015-01-26 16:51 李舜阳 阅读(378) 评论(0) 推荐(0) 编辑
摘要:原题地址非常经典的题目了。双栈法,一个普通栈,一个最小值栈入栈时:除了入普通栈之外,如果当前待入栈元素小于等于最小值栈顶元素,那么同时入最小值栈出栈时:除了出普通栈之外,如果当前待出栈元素小于等于最小值栈顶元素,那么同时出最小值栈查看栈顶元素:返回普通栈顶元素查看最小元素:返回最小值栈顶元素代码: ... 阅读全文
posted @ 2015-01-26 15:23 李舜阳 阅读(540) 评论(0) 推荐(0) 编辑
摘要:原题地址方法I:枚举依次枚举前缀,然后检验改进1:只需从长到短枚举最短的字符串的前缀改进2:检验前缀合法性时可以进行剪枝优化,加快搜索效率时间复杂度不不太好分析,加上改进之后效率还不错。方法II:字典树时间复杂度O(nm),其中n是字符串个数,m是字符串长度代码: 1 struct TrieNode... 阅读全文
posted @ 2015-01-26 15:05 李舜阳 阅读(138) 评论(0) 推荐(0) 编辑
摘要:原题地址有人些的做法是判断中序遍历序列是否是回文串,一开始我觉得挺有道理,但是琢磨了一阵觉得没那么简单。比如下面这个树: 1 / 1 / 1中序遍历序列是"111",虽然是回文串但这棵树明显不是对称的。如果要是把NULL也算进去呢?还是上面... 阅读全文
posted @ 2015-01-26 14:40 李舜阳 阅读(160) 评论(0) 推荐(0) 编辑
摘要:原题地址n!含有多少个因子10,则结尾有多少个010=2*5,而2的个数肯定比5多,所以n!含有多少个因子5,则结尾有多少个0如何计算n!有多少个因子5呢?比如n=13,则:n! = 13 * 12 * 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 ... 阅读全文
posted @ 2015-01-26 12:21 李舜阳 阅读(216) 评论(0) 推荐(0) 编辑
摘要:原题地址因为是道简单题,所以最简单的字符串匹配应该也能过,但还是练习一下KMP算法为好。KMP算法的介绍可以参考这篇以后有时间试试Boyer-Moore算法代码: 1 int strStr(char *haystack, char *needle) { 2 if (!needle[0]) ret... 阅读全文
posted @ 2015-01-26 11:50 李舜阳 阅读(169) 评论(0) 推荐(0) 编辑
摘要:原题地址方法I:排序+字典序枚举。生成字典序的方法见这里方法II:排列树(其实就是DFS)下图是一个排列树,每一层标红的字符是已经枚举完毕的部分,在后代节点中也不再变化;下划线的部分是待枚举排列的部分,在后代节点中将依次枚举。可见,排列树将问题一层一层分解为子问题,非常直观。如何从一个节点生成儿子节... 阅读全文
posted @ 2015-01-26 11:08 李舜阳 阅读(282) 评论(0) 推荐(0) 编辑
摘要:原题地址最直观的想法就是手动模拟一下,找找坐标在旋转时的规律为了方便实现,可以一层一层地旋转矩阵:先旋转最外层边框,然后再旋转次外层边框...以此类推在网上看到一种极其残暴的做法,只需要2次翻转1. 沿左下-右上对角线对称翻转2. 上下翻转还有其他变种,但基本思路都是这样,两次翻转即可搞定很神奇,以... 阅读全文
posted @ 2015-01-25 19:30 李舜阳 阅读(406) 评论(0) 推荐(0) 编辑
摘要:原题地址非常经典的一道题。可以转换成求最大连续和做,但是有更简单的方法。基于一个数学定理:如果一个数组的总和非负,那么一定可以找到一个起始位置,从他开始绕数组一圈,累加和一直都是非负的(证明貌似不难,以后有时间再补)有了这个定理,判断到底是否存在这样的解非常容易,只需要把全部的油耗情况计算出来看看是... 阅读全文
posted @ 2015-01-25 17:00 李舜阳 阅读(4193) 评论(0) 推荐(1) 编辑
摘要:原题地址遍历所有数字,统计每一位出现的次数,模3即为只出现一次的数字在那一位的情况。代码: 1 int singleNumber(int A[], int n) { 2 int count[32] = {0}; 3 4 for (int i = 0; i >= 1; 8 } 9 ... 阅读全文
posted @ 2015-01-25 16:43 李舜阳 阅读(163) 评论(0) 推荐(0) 编辑
摘要:原题地址用栈保存化简后的路径。把原始路径根据"/"切分成若干小段,然后依次遍历若当前小段是"..",弹栈若当前小段是".",什么也不做否则,入栈代码: 1 string simplifyPath(string path) { 2 vector buffer; 3 char *tok = NU... 阅读全文
posted @ 2015-01-25 16:31 李舜阳 阅读(155) 评论(0) 推荐(0) 编辑
摘要:原题地址DFS,跟求子集合的方法类似,对于任意一个元素,要么选,要么不选。代码: 1 vector > res; 2 3 void solve(vector ans, int n, int curr, int left) { 4 if (left == 0) 5 res.push_ba... 阅读全文
posted @ 2015-01-25 15:36 李舜阳 阅读(117) 评论(0) 推荐(0) 编辑
摘要:原题地址二进制码 -> 格雷码:从最右边起,依次与左边相邻位异或,最左边一位不变。例如:二进制: 1 0 0 1 1 1 0 |\|\|\|\|\|\| 格雷码: 1 1 0 1 0 0 1从二进制到格雷码有一个残暴公式: a ^ (a 二进制码:从左边第二位开始,依次与左边相邻已经解... 阅读全文
posted @ 2015-01-25 15:16 李舜阳 阅读(133) 评论(0) 推荐(0) 编辑
摘要:原题地址《Cracking the Code》一书中出现过这道题,那里面提到了多种解法,这里用最简单的枚举法。DFS枚举,令leftRemain表示当前还剩下几个"("可用,rightRemain表示当前还剩下几个")"可用。如果leftRemain > 0,那么总可以放一个"("如果leftRem... 阅读全文
posted @ 2015-01-25 13:57 李舜阳 阅读(164) 评论(0) 推荐(0) 编辑
摘要:原题地址很有意思的一道题,二分搜索求极值。题目中已经说明num[i] != num[i+1],即相邻元素不可能相等,所以相邻元素间的大小关系要么是大于,要么是小于,这就是二分搜索的判断条件。假设左边界是l,右边界是r,中点m=(l+r)/2如果num[m]比左右两边都大,那么num[m]就已经是极值... 阅读全文
posted @ 2015-01-25 13:40 李舜阳 阅读(166) 评论(0) 推荐(0) 编辑
摘要:原题地址以前可以用DP枚举所有回文串,但是Leetcode后来增加了几组大数据,用DP会超时。什么!用DP都超时了??那怎么办?答:二分法尝试可能的回文串长度,直到找到最大值需要注意的是,假设现在已经验证了长度为length的回文串不存在,传统的二分法就会去尝试长度为length/2的回文串是否存在... 阅读全文
posted @ 2015-01-24 19:40 李舜阳 阅读(198) 评论(0) 推荐(0) 编辑
摘要:原题地址1. 把所有与边界联通的"O"替换成别的字符,比如"#"2. 把剩下的所有"O"替换成"X"3. 把所有与边界联通的"#"替换成"X"代码: 1 void replace(vector > &board, int i, int j, char before, char after) { 2 ... 阅读全文
posted @ 2015-01-24 17:42 李舜阳 阅读(189) 评论(0) 推荐(0) 编辑
摘要:原题地址非常有技巧性的一道题,虽然本质上仍然是搜索+回溯,但关键是如何处理模式串里的多余的*,如果处理的不好就超时了。基本的搜索+回溯算法是这样的,对于原串s和模式串p,依次遍历其字符:(a) 如果p[j]="*",依次将p[j+1..p.length]和s[i..s.length]、s[i+1..... 阅读全文
posted @ 2015-01-24 16:19 李舜阳 阅读(1597) 评论(0) 推荐(0) 编辑
摘要:原题地址非常有技巧的一道题,如果没有接触过类似题目或没有任何提示的情况下想出来很困难,因为题目要求O(1)的空间复杂度既然是O(1)的空间复杂度,自然要用到原数组了。解法是:1. 遍历每个数组元素,把元素都交换到正确的位置上。比如发现A[3] = 5,则交换A[5]和A[3],让A[5]=5。2. ... 阅读全文
posted @ 2015-01-24 15:36 李舜阳 阅读(161) 评论(0) 推荐(0) 编辑
摘要:原题地址不妨手动模拟一下,观察是否有规律可寻。假设从位置0开始,我们有一个矩形条向右扩展,我们遇到了第二个矩形条,假设这个矩形条比第一个矮:我们继续向右扩展,直到遇到比第一个矩形条高(或者相等)的矩形条:那么显然,蓝色的部分就是装水的部分,把这部分累加到最终的结果中然后,以新发现的这个矩形条为左边界... 阅读全文
posted @ 2015-01-24 15:00 李舜阳 阅读(333) 评论(0) 推荐(0) 编辑
摘要:原题地址字典序模拟问题,枚举num的所有字典序。假设已知序列seq,求下一个字典序序列:1. 从序列seq右侧向左寻找第一个顺序对,即对于位置i,有seq[i] seq[i]。肯定能找到这样一个j,因为j至少可以是i+13. 交换seq[i]和seq[j]4. 将seq在位置i之后的部分倒置,即将... 阅读全文
posted @ 2015-01-24 14:01 李舜阳 阅读(371) 评论(0) 推荐(0) 编辑
摘要:原题地址跟N-Queens几乎没差别,好像还更简单了呢代码: 1 int solve(int row, vector &col, vector left, vector right) { 2 if (row == 0) 3 return 1; 4 5 vector avail(co... 阅读全文
posted @ 2015-01-24 02:10 李舜阳 阅读(164) 评论(0) 推荐(0) 编辑
摘要:原题地址经典的8皇后问题变形版当然也是用经典的8皇后问题解法的变形版咯(仿照"位运算求解8皇后问题")row:当前是第几行col:皇后所在的列的情况left:左上角禁位(因为我是从下向上迭代的)right:右上角禁位(因为我是从下向上迭代的)代码: 1 vector > result; 2 vect... 阅读全文
posted @ 2015-01-23 20:17 李舜阳 阅读(210) 评论(0) 推荐(0) 编辑
摘要:原题地址排序+合并,没啥好说的第一次尝试C++的lambda表达式,有种写js的感觉,很神奇c11就支持了lambda表达式,仔细想想,我学C++大概就是在09~10年,c11还没有发布,不得不说C++跟当时已经大不一样了。代码: 1 vector merge(vector &intervals) ... 阅读全文
posted @ 2015-01-23 16:38 李舜阳 阅读(142) 评论(0) 推荐(0) 编辑
摘要:原题地址回溯,没啥好说的 1 bool row[9][9]; 2 bool col[9][9]; 3 bool grid[9][9]; 4 bool mark[9][9]; 5 6 bool solve(vector > &board, int r, int c) { 7 if (r == 9... 阅读全文
posted @ 2015-01-23 16:12 李舜阳 阅读(157) 评论(0) 推荐(0) 编辑
摘要:原题地址遍历每个区间intervals[i]:如果intervals[i]在newInterval的左边,且没有交集,把intervals[i]插入result如果intervals[i]在newInterval的右边,且没有交集,如果newInterval还没插入,则将newInterval插入r... 阅读全文
posted @ 2015-01-23 15:27 李舜阳 阅读(351) 评论(0) 推荐(0) 编辑
摘要:原题地址一道考察"工程"能力的好题,但是你丫能说明一下规则不。。用状态机求解:当遍历完字符串后:1. 绿色的状态至少要出现1个2. 红色的状态不能作为终结状态代码: 1 enum Status { 2 PRE_PADDING, 3 SIGN, 4 NUMBER_BEFORE_POINT,... 阅读全文
posted @ 2015-01-23 15:09 李舜阳 阅读(384) 评论(0) 推荐(0) 编辑
摘要:原题地址没有复杂的算法,纯粹的模拟题先试探,计算出一行能放几个单词然后计算出单词之间有几个空格,注意,如果空格总长度无法整除空格数,前面的空格长度通通+1最后放单词、放空格,组成一行,加入结果中对于最后一行要特殊处理代码: 1 vector fullJustify(vector &words, in... 阅读全文
posted @ 2015-01-23 12:26 李舜阳 阅读(184) 评论(0) 推荐(0) 编辑
摘要:原题地址跟Find Minimum in Rotated Array类似,折半查找将A平均分成两半A[l..m]和A[m+1..r]如果target可能出现在A[l..m],则保留A[l..m],去掉A[m+1..r]反之,保留A[m+1..r],去掉A[l..m]。根据区间的连续性判断target... 阅读全文
posted @ 2015-01-23 11:41 李舜阳 阅读(154) 评论(0) 推荐(0) 编辑
摘要:原题地址方法I:动态规划len[i]表示从i开始到结束的最长合法括号串长度,则:如果s[i] == "(" 且 s[i+len[i+1]+1]==")",len[i] = len[i+1] + 2否则len[i] = 0方法II:辅助栈跟那个直方图求最大面积有点类似,用一个栈保存合法括号串的长度,显... 阅读全文
posted @ 2015-01-23 02:37 李舜阳 阅读(213) 评论(0) 推荐(0) 编辑
摘要:原题地址教科书般经典的动归题目,也可以看作是地图寻路问题。例如word1="ceab",word2="abc",构造如下地图。其中"^"表示起点,"$"表示终点,则题目转化成了寻找一条从起点到终点的最短路径。 a b c c ^ . . e . . . ... 阅读全文
posted @ 2015-01-23 01:59 李舜阳 阅读(200) 评论(0) 推荐(0) 编辑
摘要:原题地址将L中的单词看成一个整体,这道题与Minimun Window String比较类似,都是利用滑动窗口搜索。所以,依次枚举所有S的起始位置i,从i处开始搜索。当然并不需要枚举所有的i,i最多等于L中单词长度-1。比如L中的单词长度为3,那么当枚举过i=0,1,2后,不用再尝试i=3了,因为结... 阅读全文
posted @ 2015-01-22 18:23 李舜阳 阅读(902) 评论(0) 推荐(0) 编辑
摘要:原题地址用两个指针分别记录窗口的左右边界,移动指针时忽略那些出现在S种但是没有出现在T中的字符1. 扩展窗口。向右移动右指针,当窗口内的字符即将多于T内的字符时,停止右移2. 收缩窗口。向右调整左指针,当窗口内的字符即将少于T内的字符时,停止右移3. 统计结果。如果窗口内的字符包含了T内的所有字符,... 阅读全文
posted @ 2015-01-22 15:11 李舜阳 阅读(575) 评论(0) 推荐(0) 编辑
摘要:原题地址两个字符串满足什么条件才称得上是scramble的呢?如果s1和s2的长度等于1,显然只有s1=s2时才是scramble关系。如果s1和s2的长度大于1,那么就对s1和s2进行分割,划分成两个子问题分别处理。如何分割呢?当然不能任意分割。假设分割后s1变成了s11和s12,s2变成了s21... 阅读全文
posted @ 2015-01-22 12:09 李舜阳 阅读(345) 评论(0) 推荐(0) 编辑
摘要:原题地址分两步:1. 试探。看是否还有k个节点可以翻转2. 翻转。[]->[]->[]->[1]->[2]->[3]->[4]->[]->[]->[]->NULL |------------------| 假设要翻转这一段翻转前: ... 阅读全文
posted @ 2015-01-21 19:57 李舜阳 阅读(167) 评论(0) 推荐(0) 编辑
摘要:原题地址转化为二维地图游走问题。比如s1="abab",s2="aab",s3="aabaabb",则有如下地图,其中"^"表示开始位置,"$"表示终止位置。 a a b a ^ . . b . . . a . . . b .... 阅读全文
posted @ 2015-01-21 16:31 李舜阳 阅读(192) 评论(0) 推荐(0) 编辑
摘要:原题地址中序遍历二叉搜索树,正常情况下所有元素都应该按递增排列,如果有元素被交换,则会出现前面元素大于后面的情况,称作反序。由于交换了两个节点,所以通常会有两处反序,但如果是两个相邻节点发生了交换,则只会有一次反序。注意,如果有两次反序,前面那次一定是较大数,后面那次一定是较小数交换的时候注意只需要... 阅读全文
posted @ 2015-01-21 15:24 李舜阳 阅读(171) 评论(0) 推荐(0) 编辑
摘要:原题地址转化为求非重路径数问题,用动态规划求解,这种方法还挺常见的举个例子,S="aabb",T="ab"。构造如下地图("."表示空位,"^"表示起点,"$"表示终点),我们的目标就是求从起点到终点一共有多少条路径。 a ba ^ .a . .b . .b . $ 对于任意一个位... 阅读全文
posted @ 2015-01-21 14:47 李舜阳 阅读(119) 评论(0) 推荐(0) 编辑
摘要:原题地址二叉树的层次遍历。对于每一层,依次把各节点连起来即可。代码: 1 void connect(TreeLinkNode *root) { 2 if (!root) return; 3 4 queue parents; 5 6 parents.push(root); 7 wh... 阅读全文
posted @ 2015-01-21 14:03 李舜阳 阅读(326) 评论(0) 推荐(0) 编辑
摘要:原题地址最直观的想法就是划分成两个子问题,每个子问题变成了:求在某个范围内交易一次的最大利润在只能交易一次的情况下,如何求一段时间内的最大利润?其实就是找股价最低的一天买进,然后在股价最高的一天卖出,当然,卖股票要在买股票之后。用迭代法求这个问题非常容易,令profits[i]表示截至到第i天的最大... 阅读全文
posted @ 2015-01-21 13:08 李舜阳 阅读(883) 评论(0) 推荐(0) 编辑
摘要:原题地址假设我们找到了一个最优路径,那么该路径上一定存在一个节点,左边的路径是它的左儿子,右边的路径是它的右儿子。所以,只需要在遍历二叉树求路径的同时更新最大值即可。maxPath = max{只保留左边路径,只保留右边路径,同时保留左右两边路径,左右两边路径都不保留(只有节点本身)},对应第8行无... 阅读全文
posted @ 2015-01-21 12:00 李舜阳 阅读(375) 评论(0) 推荐(0) 编辑
摘要:原题地址既然是求最短路径,可以考虑动归或广搜。这道题对字典直接进行动归是不现实的,因为字典里的单词非常多。只能选择广搜了。思路也非常直观,从start或end开始,不断加入所有可到达的单词,直到最终到达另一端。本质上广度优先遍历图。需要注意的是,拓展下一个单词时不能对字典进行枚举,因为字典里的单词太... 阅读全文
posted @ 2015-01-21 11:23 李舜阳 阅读(1442) 评论(0) 推荐(0) 编辑
摘要:原题地址1. 把所有元素都塞到集合里2. 遍历所有元素,对于每个元素,如果集合里没有,就算了,如果有的话,就向左向右拓展,找到最长的连续范围,同时在每次找的时候都把找到的删掉。这样做保证了同样的连续序列只会被遍历一次,从而保证时间复杂度。时间复杂度O(n)代码: 1 int longestConse... 阅读全文
posted @ 2015-01-20 16:16 李舜阳 阅读(176) 评论(0) 推荐(0) 编辑
摘要:原题地址动态规划题。最直观的想法就是用cut[i][j]表示子串s[i..j]的最小分割数,则有如下规则:1. 如果s[i..j]是回文串,则cut[i][j]=02. 如果s[i..j]不是回文串,则枚举分割点,将原字符串切成两个子串,求解子问题。递推公式:cut[i][j] = min{cut[... 阅读全文
posted @ 2015-01-20 15:55 李舜阳 阅读(312) 评论(0) 推荐(0) 编辑
摘要:原题地址遍历所有小孩的分数1. 若小孩的分数递增,分给小孩的糖果依次+12. 若小孩的分数递减,分给小孩的糖果依次-13. 若小孩的分数相等,分给小孩的糖果设为1当递减序列结束时,如果少分了糖果,就补上,如果多分了糖果,就减掉究竟补多少或减多少,这很容易计算,不啰嗦了。时间复杂度:O(n)代码: 1... 阅读全文
posted @ 2015-01-20 14:45 李舜阳 阅读(197) 评论(0) 推荐(0) 编辑
摘要:原题地址非常巧妙的方法,不需要用map,只需要O(1)的额外存储空间,分为3步:1. 先复制链表,但是这个复制比较特殊,每个新复制的节点添加在原节点的后面,相当于"加塞"2. 根据原节点的 ramdon 指针构造新节点的 random 指针3. 恢复原链表结构,同时得到新复制链表时间复杂度:O(n)... 阅读全文
posted @ 2015-01-20 14:17 李舜阳 阅读(149) 评论(0) 推荐(0) 编辑
摘要:原题地址动态规划题令s[i..j]表示下标从i到j的子串,它的所有分割情况用words[i]表示假设s[0..i]的所有分割情况words[i]已知。则s[0..i+1]的分割情况words[i+1] = words[k] + s[k+1..i+1],其中(有三个条件要满足)(1) 0 wordB... 阅读全文
posted @ 2015-01-20 13:54 李舜阳 阅读(942) 评论(0) 推荐(0) 编辑
摘要:原题地址这道题坑了我很久,有一组测试数据在本地跑结果是true,但是在Leetcode服务器上跑结果就是false,让我百思不得其解。后来费了好久才终于找到原因,原来还是自己的代码不够严谨,为了让代码简洁一些,有一个判断语句默认空闲内存都是0,结果就错了。这道题没有什么技巧,匹配的思路很直观,如果当... 阅读全文
posted @ 2015-01-20 11:28 李舜阳 阅读(208) 评论(0) 推荐(0) 编辑
摘要:原题地址递归写法谁都会,看看非递归写法。对于二叉树的前序和中序遍历的非递归写法都很简单,只需要一个最普通的栈即可实现,唯独后续遍历有点麻烦,如果不借助额外变量没法记住究竟遍历了几个儿子。所以,最直接的想法就是在栈中记录到底遍历了几个儿子。代码: 1 vector postorderTraversal... 阅读全文
posted @ 2015-01-19 17:08 李舜阳 阅读(498) 评论(0) 推荐(0) 编辑
摘要:原题地址以前Leetcode的测试数据比较弱,单纯用链表做也能过,现在就不行了,大数据会超时。通常大家都是用map+双向链表做的。我曾经尝试用C++的list容器来写,后来发现map没法保存list的iterator,总是报错,我也不知道为什么。后来只好手写双向链表,真是痛苦啊,一不小心就会出错。怪... 阅读全文
posted @ 2015-01-19 16:11 李舜阳 阅读(229) 评论(0) 推荐(0) 编辑
摘要:原题地址方法I:固定一个点,枚举剩下的点所构成直线(斜率)先固定一个点,然后计算该点到其他所有点的斜率,最后统计得到最多的共线的点的个数。时间复杂度为O(n^2),需要借助map数据结构保存中间结果,空间复杂度为O(n)。这种方法最大的问题是需要计算斜率,需要用到除法,可能会有数据精度的问题。方法I... 阅读全文
posted @ 2015-01-19 14:03 李舜阳 阅读(628) 评论(0) 推荐(0) 编辑
摘要:原题地址说个题外话,我一直想不明白题目里rotate这个词,感觉用shift更合适啊仔细分析题目,有如下两个性质:1. 对于一个没有折叠过的数组,最小值一定是第一个元素。2. 对于一个折叠过的数组,最小值一定出现在折叠的地方。因此,要找最小值,就把以上两种情况下的最小值都看看,选一个最小的就行了。这... 阅读全文
posted @ 2015-01-19 11:50 李舜阳 阅读(457) 评论(0) 推荐(0) 编辑
摘要:原题地址这道题跟最大子矩阵的思想比较类似,都是降一维(减少变量数量)转化成简单问题指定任意一行作为矩形的下边界,那么问题就变成了求直方图的最大面积的矩形,参见之前的这篇文章。所以思路就是,从上到下,依次求直方图最大面积矩形,感觉瞬间没有难度了。下面的代码里,第一个函数就是原封不动搬过来的。。时间复杂... 阅读全文
posted @ 2015-01-18 17:16 李舜阳 阅读(596) 评论(0) 推荐(0) 编辑
摘要:原题地址有两种方法,左右扫描或辅助栈。方法I: 左右扫描法考虑到最大面积的矩形高度一定跟某个条一样高,所以挨个枚举每个条,看其向左、向右最多能延伸到多远。在计算左右边界时,可以借助之前计算过的结果迭代(类似动归的感觉)优化以减少时间复杂度,这应该算是唯一的难点了。总的来说,向左一遍,向右一遍,整体求... 阅读全文
posted @ 2015-01-18 16:34 李舜阳 阅读(5037) 评论(1) 推荐(0) 编辑
摘要:原题地址最朴素的想法是,对于每个位置,挨个尝试一遍不同的跳法,这样总能找到最优解,最坏情况下A[i]=n,那么时间复杂度为O(n^2)。显然会超时,所以在这个朴素的算法上改进。如果用动态规划求解,考虑如何划分子问题。一个很自然的想法是将起跳点为子问题边界,令p[i]表示从第i个位置起跳,到终点所需最... 阅读全文
posted @ 2015-01-18 14:55 李舜阳 阅读(1068) 评论(0) 推荐(0) 编辑
摘要:原题地址将“寻找中位数”转化成更一般化的“寻找第k大的数”这个问题。因为数组已经排序,所以可以使用二分缩小范围,使得时间复杂度满足要求。假设A、B数组里都至少有k/2个元素,那么可以将k平均划分成k/2和k/2两半,在A里找第k/2大的元素,在B里找k/2大的元素(对k划分,解题的关键)。因为数组已... 阅读全文
posted @ 2015-01-18 14:04 李舜阳 阅读(178) 评论(0) 推荐(0) 编辑
摘要:原题地址方法I:辅助数据结构用一个map保存遇到的值和位置,最直观的想法。遍历numbers,对于每个元素numbers[i]:如果在map中找到了target-numbers[i],说明找到了这两个数字,算法结束否则,将numbers[i]和所在位置i加入map中时间复杂度O(n),空间复杂度O(... 阅读全文
posted @ 2015-01-18 13:42 李舜阳 阅读(420) 评论(0) 推荐(0) 编辑

点击右上角即可分享
微信分享提示