自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(120)
  • 收藏
  • 关注

原创 非递归遍历二叉树

前序遍历: /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class

2014-01-09 23:20:37 770

原创 Edit Distance

典型的二维动态规划,具体的在这盘文章里讲得很清楚: http://blog.unieagle.net/2012/09/19/leetcode%E9%A2%98%E7%9B%AE%EF%BC%9Aedit-distance%EF%BC%8C%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B9%8B%E9%97%B4%E7%9A%84%E7%BC%96%E8%BE%91%E8%B7%9

2014-01-08 23:28:53 813

原创 Clone Graph

此题的答案非常简洁巧妙,看似用的是BFS,实则为DFS。 使用一个Map来记录克隆的旧新节点关系,然后设计一个函数,参数为node,表明这个函数要克隆node节点及其邻居关系。如果邻居就在Map里,直接返回,因为这是一个已经克隆过的邻居,否则,递归地克隆其邻居。 /** * Definition for undirected graph. * struct UndirectedGraphN

2014-01-08 21:58:01 465

原创 Copy List with Random Pointer

自然的想法是利用Hash,先把原链表从头到尾扫一次,扫的过程中生成新的节点,并且建立这样的映射表,。在扫第二次的时候,根据原链表的链接关系把新生成的链表节点连好就好了。 /** * Definition for singly-linked list with a random pointer. * struct RandomListNode { * int label; *

2014-01-08 20:51:45 404

原创 求数组中的逆序对数目(POJ1007)

这个题真心写丑了,不过当做练习还是很不错的。 思想就是利用归并排序的办法,先计算左右两个子数组的逆序对数目,把他们加起来。然后用两个指针指向子数组的头,如果前面的子数组目前元素较大,就把后面子数组的头部元素插入结果数组;否则,前面的元素应该进入结果数组了,此时,结果数组里的后面子数组元素个数即为此元素造成的逆序对的个数。 #include #include #include #inclu

2014-01-07 15:49:09 536

原创 Container With Most Water

题目也很有意思。当然最先想到的就是暴力搜索啦,不过猪都知道暴力搜索肯定过不了测试数据的,那么怎么办呢? 设置两个指针,i和j,起初指向两头,算一下能围成的最大面积,然后,如果height[i]小,i后移;height[j]小,j前移;相等的话,两个都向中间移。最后i和j相遇时记录到的最大值就是答案了。 为什么可以如此做呢?简单的说就是木桶原理……在我们计算完围成的面积准备移动指针的时候,到底该

2014-01-04 23:23:43 404

原创 Convert Sorted List to Binary Search Tree

这题跟前面那个数组转化为二叉平衡搜索树一样一样的啊,本来还想着怎么利用一下链表的特性呢,结果发现每次找中点都会变得特麻烦,想想还是算了,还不如先放在一个数组里然后用之前的方法做。 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; *

2014-01-04 22:53:09 421

原创 Simplify Path

这个题做得好顺利啊好开心啊哈哈哈哈!! 看题目觉得思路是有的,文件夹的结构不就是一棵树嘛,于是只要按路径读下来,把树维护好就可以了。 于是写了一个辅助程序,用来读取下一个目录名。目录名里不包括'/',并且如果是连着两个'/'的话,就返回空串。 接下来是主程序时间,先生成一个根,注意,由于根的'..'文件夹还是他自己,因此将根节点的父节点指向他自己。然后维护一个now指针,指向目前所在的目录。

2014-01-03 23:27:10 422

原创 First Missing Positive

这个题要是允许申请空间的话,那实在是没什么好说的了。如果不允许使用额外空间的话,就要考虑对给定的数组做一些手脚。 我们把A[i]放上i + 1,并且如果换回来的数还没在合适的位置,就继续换。将整个数组处理完成后,所有的小于等于n的正数都应该在合适的位置了。最后再扫一次,找到A[i]里不是i + 1的那个数。 class Solution { public: int firstMissi

2014-01-02 23:27:19 352

原创 4Sum

和2Sum一样样的,只能降低一个量级的复杂度到O(n^3)。 这点代码里还杂糅了一些其他的东西,比如如何跳过重复的元素,当答案里不要重复元素的时候,这个方法很有用。 class Solution { public: vector > fourSum(vector &num, int target) { vector> res; if (num.size(

2014-01-02 22:49:44 329

原创 Decode Ways

非常类似于上楼梯问题,一次可以选择上一阶,也可以选择上两阶,最后问有多少种上法。 但是这个题要难一些,因为要判断0出现的地方以及策略,但是实际上如果想清楚的话也很简单。 使用一个递归函数,参数start为将要处理的下标。 如果start为字符串长度,说明已经到末尾,这样便有一种译码方法,返回1;如果start指示位置为0,或者大于字符串长度,说明start位置不合法,没有译码方法,返

2014-01-02 22:03:11 380

原创 在两个有序数组中寻找第k个元素

这个问题很经典,有必要好好梳理一下: 函数的参数设定为,数组A,A的长度m,数组B,B的长度n,需要找的k。 如果m + n 如果m和n其一为0,那么就应该返回另一个数组的k - 1位置的元素;否则,将A(近似地)平均分为两部分,记其分点下标为i = m / 2,B也如此做,其分点下标为j = n / 2。假设A[i] 如此,B[j]将不小于B中它之前的所有元素,并且也不小于A[i

2014-01-01 22:31:49 970

原创 利用快速排序的思想寻找乱序数组第k大数

首先选择轴值,利用快速排序思路将轴值放到合适位置,如果轴值位置恰好在第k位置上,那么轴值便是需要找的值,否则,如果轴值位置大于k,说明要找的数在左半部分;反之则在右半部分。 import java.util.Collections; import java.util.Vector; public class FindKth { private static int findKth(int[]

2014-01-01 20:52:53 593

原创 归并排序的Java实现

public class MergeSort { private static void mergeSort(int[] A, int start, int end) { if (start >= end) return; int mid = start + (end - start) / 2; mergeSort(A, start, mid); mergeSort(A,

2014-01-01 20:48:02 361

原创 Quick Sort的Java实现

public class QuickSort { private static void quickSort(int[] A, int start, int end) { if (start >= end) return; int pivot = A[start]; int i = start, j = end; while (i < j) { while (j >

2014-01-01 20:47:09 609

原创 Scramble String

粗暴,直接,递归下去即可。 首先如果俩串长度不一,则定不满足要求。之后,统计各个字符出现次数,都相同者,才有可能满足题目要求。 接下来,将s1,s2分别划开,则要么不交换满足题目要求,要么左右交换满足题目要求,将划开的位置遍历,分别测试即可。 class Solution { public: bool isScramble(string s1, string s2) {

2013-12-29 22:50:22 439

原创 Combination Sum II

用set过滤掉重复的答案即可,一种偷懒的办法。 class Solution { public: vector > combinationSum2(vector &num, int target) { sort(num.begin(), num.end()); vector path; set> res; helper(nu

2013-12-29 20:30:14 326

原创 Permutations II

维护一个map,里面记录各个元素有多少个即可。这样就保证不同但值相同的元素不可能反复出现在同一位置。 class Solution { public: vector > permuteUnique(vector &num) { map myMap; for (int i = 0; i < num.size(); ++i) myMap

2013-12-29 15:57:27 367

原创 Longest Palindromic Substring

简单的动态规划,一个子串两头相等的话,它是不是回文的就取决与掐掉两头后剩下的部分是不是回文的。 网上有O(n)的解法,不过等我有时间了再看吧。 class Solution { public: bool DP[1001][1001]; string longestPalindrome(string s) { memset(DP, false, sizeof(DP

2013-12-29 15:29:44 365

原创 Merge k Sorted Lists

传说中的K路归并排序问题,显然我们应该用一个最小堆来维护K个链表头里的最小值。 因此这个题的关键就变成了,如何使用STL里的优先队列。 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val

2013-12-29 11:49:47 413

原创 ZigZag Conversion

中间斜上去的部分完全可以压成一个纵列,因此按顺序将字符填到表的合适位置,再将表按顺序输出即可。 代码写丑了,网上有更简洁的答案。 class Solution { public: string convert(string s, int nRows) { if (s == "" || nRows == 1) return s; i

2013-12-28 23:11:39 372

原创 Reverse Nodes in k-Group

思路很简单,首先得有一个辅助函数,将链表head到tail之间的部分翻转。这个函数用递归写起来很简单,并且容易理解,强烈推荐!然后就是用两个p,q指针不停滑动翻转链表的事情了,记住我们需要把p的前驱pre记下来,不然翻转以后就连不上了。 /** * Definition for singly-linked list. * struct ListNode { * int val;

2013-12-28 22:24:56 349

原创 Palindrome Partitioning

这道题的思路很直接,也是利用了动态规划的思路。 首先用一个二维数组,palin[i][j],记录s中从i到j的子串是不是回文子串。然后便可以处理了,用递归来求解,假设目前处理到start开始的位置,将start定为首字母,尾字母则从start一直扫到序列末尾,如果中间这部分是回文的,那么start就移到尾字母+1的位置,继续判断后面的子串里的回文序列。 class Solution { pub

2013-12-28 21:51:42 331

原创 Letter Combinations of a Phone Number

class Solution { public: vector letterCombinations(string digits) { string tele[] = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; vector res; string p

2013-12-27 14:55:15 333

原创 Longest Valid Parentheses

用一个栈来压入左括号的下标,然后用last来记录无法匹配的右括号的下标。 遍历s,如果是左括号,下标入栈。如果是右括号,假如此时栈为空,表明这个右括号无法被匹配,用last记下来,表示这是无法匹配的括号对的末尾。如果栈不空,就弹出一个元素,和这个右括号匹配之。接下来,如果栈为空,表明从上一个无法匹配的末尾开始,匹配完美结束,计算最长连续长度;否则栈不空,表明左括号还没用完,但是这个时候依然需要计

2013-12-26 22:41:19 362

原创 Longest Consecutive Sequence

如果可以使用排序的话就很容易了,但是这无法满足题目的要求,即在O(n)的时间内完成。 那么只好考虑使用hash的情况,首先将所有元素都插入到hash中。然后考察每一个元素,考察时,判断比他小一号的在不在hash里,直到不在为止;然后判断比他大一号的在不在,直到不在为止。这样就可以得到本元素在内的最长连续序列了。 这里有一个小窍门,每当我找到一个在连续序列里的元素的时候,我就把他从hash中删除

2013-12-26 20:48:36 417

原创 Interleaving String

这种问题一看就是典型的动态规划问题,但是不好做啊。 s1 = a1 a2 ... ai s2 = b1 b2 ... bj s3 = c1 c2 ... c(i + j) 下面进行考察, 如果ai == c(i + j),那么问题变为考察a1 a2 ... a(i - 1),b1 b2 ... bj,c1 c2 ... c(i + j - 1)是否匹配;如果bj == c(i +

2013-12-25 15:42:54 345

原创 Valid Palindrome

最简单的题了,先预处理一下会比较好做。 class Solution { public: bool isPalindrome(string s) { s = preProcess(s); int l = 0, r = s.length() - 1; while (l < r) { if (s[l] == s[r])

2013-12-25 10:55:03 331

原创 Word Search

我用的简单的深搜而已,不知道有更好的方法么?先把我的贴在这里好了。 class Solution { public: bool exist(vector > &board, string word) { int p, q; vector> used(board.size(), vector(board[0].size(), false)); for (int i = 0; i <

2013-12-22 23:34:16 430

原创 Construct Binary Tree from Preorder and Inorder Traversal

和另外一个题完全类似。 /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */

2013-12-22 22:57:17 401

原创 Insert Interval

一个一个判断,如果某个旧区间的end值比新区间的start还小,那么就没他什么事儿了,将他直接插入到结果里。反之,取旧区间和新区间start里较小的那个作为start值。接下来继续一个个判断,如果某旧区间end比新区间end还小,那么没他事儿,直接忽略,这段已经被新区间给盖住了。反之,需比较旧区间end与此区间start,来判断end应该取什么值。最后将剩下的区间们拷贝过去就完事儿了。 /**

2013-12-22 21:56:46 359

原创 Triangle

自底向上。 class Solution { public: int minimumTotal(vector > &triangle) { int i = triangle.size(); if (i <= 0) return -1; for (i = i - 2; i >= 0; --i) {

2013-12-22 20:51:56 321

原创 Populating Next Right Pointers in Each Node II

广搜妥妥的,但是似乎不符合题目要求的只能用常数空间?有人用了递归解法,但是递归算不算常数空间呢? /** * Definition for binary tree with next pointer. * struct TreeLinkNode { * int val; * TreeLinkNode *left, *right, *next; * TreeLinkNode(int

2013-12-22 15:52:17 344

原创 Pascal's Triangle II

不容易呀,观察一下写出来的图形就很容易明白这个代码是干什么的了。 0  1 1  1 1 2  1 2 1 3  1 3 3 1 4  1 4 6 4 1 class Solution { public: vector getRow(int rowIndex) { vector res(rowIndex + 1, 0); for (int i =

2013-12-22 15:29:29 362

原创 Remove Duplicates from Sorted Array II

代码好理解,维护一个occur变量,记录出现次数。 class Solution { public: int removeDuplicates(int A[], int n) { if (n <= 1) return n; int curr = 1, i = 1; int occur = 1; whi

2013-12-22 15:11:39 338

原创 Rotate Image

先沿着左上-右下对角线对折一下,然后再沿着竖直中线对折。如下: 1  2    ->    1  3    ->    3  1 3  4            2  4           4  2 呆逼的我在做第一步的时候i, j从头到尾扫了个遍,结果效果和什么都没做一样。注意了!这里只要换少一半就行了,对角线上及另一侧不用再考虑了! class Solution { public:

2013-12-22 13:55:35 359

原创 Remove Element

记录新数组的长度,从前向后遍历,如果找到了目标元素,就将数组最后一个元素移过来,然后数组长度递减。需要注意的是,由于移过来的元素还有可能是目标元素,因此这个元素需要被再次检验。 class Solution { public: int removeElement(int A[], int n, int elem) { int new_len = n; in

2013-12-22 13:29:16 309

原创 Pascal's Triangle

理清思路,还是很简单的。从上往下依次构建即可。 class Solution { public: vector > generate(int numRows) { vector> res; if (numRows == 0) return res; res.push_back(vector(1, 1));

2013-12-21 23:25:28 318

原创 Construct Binary Tree from Inorder and Postorder Traversal

后序遍历的最后一个点肯定是树根,然后在中序遍历里找到这个树根,如此, 便得到两个子树,依次递归下去即可。 /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val

2013-12-21 21:31:32 424

原创 Spiral Matrix

跟上一个类似。 class Solution { public: vector spiralOrder(vector > &matrix) { vector res; if (matrix.size() == 0) return res; int size = matrix.size() * matrix[0].si

2013-12-21 19:30:55 341

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除