算法
文章平均质量分 51
nandawys
这个作者很懒,什么都没留下…
展开
-
LeetCode - Word Ladder
这道题用图的广度优先搜索。先是建一张图,需要O(N2)复杂度。大数据超时,发现不需要建图,直接遍历dict查找邻居放入队列,再从dict中删除,这样复杂度应该是O(答案长度*N)。N是dict长度。结果还是超时。参考网上比较多的不用遍历dict查找,而利用hashset的O(1)的访问性质,因为是字符串,所以可以通过O(字符串长度*24)即可获得所有邻居。因为题目中字符串长度都很短,所原创 2013-06-17 22:10:35 · 549 阅读 · 0 评论 -
LeetCode - Distinct Subsequences
这道题乍一看首先想到的是暴力搜索,递归搜索。显然对于有大量重复字符的字符串其复杂度太高,已经不是多项式的复杂度了。所以那肯定只能是用动态规划DP了。只要找到转移方程就比较容易实现了。对于string S 和 T, 定义 f[i][j] = T前j个字符 在 S前i个字符中的Distinct Subsequences个数。方程如下:if(S[i-1] == T[j-1])f[i][原创 2013-06-18 21:24:37 · 231 阅读 · 0 评论 -
LeetCode - Convert Sorted List to Binary Search Tree
本来以为题目比较简单,就是每次以中间元素作为父节点递归简历左右子树。优化:先把链表元素存入vector中,便于快速存取中间元素。/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val原创 2013-06-19 01:34:39 · 263 阅读 · 0 评论 -
LeetCode - Flatten Binary Tree to Linked List
递归建树,递归函数返回 以给定节点为根的子树flatten后最后一个节点。还是比较简单。/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val原创 2013-06-19 14:30:32 · 204 阅读 · 0 评论 -
LeetCode - Binary Tree Level Order Traversal II
这一类题都是一个套路。跟之前的Zigzag没什么太大的区别,把Zigzag的代码拿来改一下就能用了。不需要之字形层次遍历了,直接顺序存放即可。从顶向底遍历,然后reverse一下即可。/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; *原创 2013-06-19 15:04:51 · 185 阅读 · 0 评论 -
LeetCode - Recover Binary Search Tree
题目大意是 一颗二叉搜索树有两个元素交换了位置,要找到这两个节点,然后将其值交换回来。二叉搜索树的中序遍历得到的值序列 应该是个递增序列。容易发现从 中序遍历序列 中可以找到这两个错误的值,然后将其交换即可。简单直白的方法是中序遍历该树,将其节点指针和值 存入数组或vector中。然后找到两个错误值并利用指针交换其值。空间复杂度显然O(N)。更简洁的方法是递归遍历的时候直接比较。时原创 2013-06-19 16:43:09 · 236 阅读 · 0 评论 -
LeetCode - Interleaving String
暴力搜索的话比较简单但是显然是过不了大数据的。class Solution {public: bool _isInterleave(string &s1, string &s2, string &s3, int start1,int start2,int start3){ if(start3 == s3.length()) return true; if( (sta原创 2013-06-20 13:45:43 · 185 阅读 · 0 评论 -
LeetCode - Reverse Linked List II
比反转整个链表麻烦了一点点。也是简单的。/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solutio原创 2013-06-20 19:21:12 · 161 阅读 · 0 评论 -
LeetCode - Simplify Path
简化Unix下的路径。".."表示上一层,"."表示当前目录。简单的方法是把/划分的各个部分(文件名)放入数组A中,然后把其中元素(文件名)按照规则放入另一数组B。遇到“..”就删除B尾部文件名,遇到“.”跳过,其余放入B尾部。class Solution {public: string simplifyPath(string path) { string res;原创 2013-07-05 16:53:49 · 224 阅读 · 0 评论 -
LeetCode - Set Matrix Zeroes **
这题有点意思。很容易想到的O(m+n)的思路是用记录每一行每一列是否清零的信息,需要O(m+n)空间,然后进行清零操作。如果要常数空间复杂度,则可以用第一行和第一列的元素保存行和列的清零标志。那原来第一行第一列的元素丢失了怎么办?可以用额外两个bool先进行判断,判断第一行第一列是否清零!因为Matrix[0][0]可以保存第0行的清零信息,所以只需要一个bool变量保存第一列是否原创 2013-07-05 20:37:56 · 352 阅读 · 0 评论 -
LeetCode - Unique Binary Search Trees II
要求返回所有可能结构的树,递归可破。没什么好说的。/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(原创 2013-07-06 15:40:23 · 149 阅读 · 0 评论 -
LeetCode - Subsets II
组合数学的全组合问题。递归套路。用STL的算法先排序再去除重复元素很省事儿。class Solution {public: void _subsets(vector &S, int start,vector > &res, list &lst){ if(start == S.size()){ res.push_back(vector(lst.be原创 2013-07-06 19:47:56 · 200 阅读 · 0 评论 -
LeetCode - Decode Ways
一眼看上去就不是用递归暴力搜索来做,肯定超时,而且也没有DP实现起来简洁。用DP做,特别要注意一些转移方程的细节。1 如当前为0的话,上一个数字必须是1或2。2 如上一个数字是0或者>=3,则上一个数字不能和当前数字结合。3 如上一个数字是2,则当前数字为7-9的话不能结合。4 如上一个数字是1,则可与当前数字结合。若一次性可以Pass则一些判定处理的很好。看L原创 2013-07-06 20:24:32 · 287 阅读 · 0 评论 -
LeetCode - Gray Code ***
哎这道题开始想麻烦了,一直在寻找规律。其实没有什么规律,用一个set保存已有序列,cur对应当前序列。 对cur从低位到高位依次判断改变位值后是否为新的序列,如是则加入set,并更新cur。如已存在则继续判定更高位。如果所有位的改变都不能产生新的序列,则结束。我只能说这是个"笨方法"了,在没有更好的方法之前。 vector grayCode(int n) {原创 2013-07-06 21:08:31 · 477 阅读 · 0 评论 -
LeetCode - Search in Rotated Sorted Array II
如果有重复元素的话很麻烦,所以干脆先把重复元素去掉,然后再查找就很简单了。。空间复杂度为O(N),用到额外的数组存放去除重复后的元素。如果原地去除重复元素的话就不需要额外空间了,但是破坏了原有数组。class Solution {public: bool search(int A[], int n, int target) { vector v(n); v[0]原创 2013-07-07 17:53:17 · 190 阅读 · 0 评论 -
LeetCode - Remove Duplicates from Sorted Array II
比较简单。线性扫描,用一个变量记录相同元素个数即可。class Solution {public: int removeDuplicates(int A[], int n) { if(n<3) return n; int count = 1; int start = 1, idx = 0; while(start<n){ if(A[start]原创 2013-07-07 18:01:53 · 178 阅读 · 0 评论 -
LeetCode - Binary Tree Inorder Traversal
二叉树非递归中序遍历。用一个栈存储父节点即可。每次push右节点的时候要循环push右键点的左节点,这样pop出就可以直接访问了。/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * Tr原创 2013-06-20 15:28:14 · 189 阅读 · 0 评论 -
LeetCode - Merge Sorted Array
肯定是要求空间复杂度为O(1)的,不然就太简单了。计算好合并后A的最后一个位置, 然后A和B从后向前比较大小, 从后向前放置A和B中较大的元素。class Solution {public: void merge(int A[], int m, int B[], int n) { int last = m+n-1; while(m>0 && n>0){ if原创 2013-06-20 20:23:08 · 201 阅读 · 0 评论 -
LeetCode - Scramble String
这题目比较新颖。S1字符串从根部开始二叉划分,直到叶节点。从最高层的根部节点看。S1存在一个划分,其中A部分和B部分互为Scramble,或者A部分和C部分互为Scramble。因此从顶向下可以采用递归的方式,不停寻找这样的划分。class Solution {public: bool _equal(string &s1, int start1,int e原创 2013-06-20 22:37:38 · 220 阅读 · 0 评论 -
LeetCode - Binary Tree Zigzag Level Order Traversal
没什么难度的题。用两个vector v1和v2, v2作为临时向量保存v1中节点的孩子,即v1节点下一层的节点,然后交换v1和v2。这道题有memory limit,如果把所有节点都存下来再层次遍历的话 应该是 空间复杂度 会过不了。/** * Definition for binary tree * struct TreeNode { * int val原创 2013-06-19 14:58:04 · 254 阅读 · 0 评论 -
LeetCode - Validate Binary Search Tree
中序遍历结果放入一个数组中,判断数组是否升序即可。/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(原创 2013-06-20 13:19:32 · 144 阅读 · 0 评论 -
LeetCode - Word Search
一眼看上去是道图的深度优先搜索的题目。每个节点上下左右都有边。选定一个节点开始搜索,写起来还是蛮简单的,注意边界的条件判断。class Solution {public: bool _exit(vector > &board, vector > &visit,string word, int start, int i, int j){ if(start == word原创 2013-07-07 20:05:41 · 209 阅读 · 0 评论 -
LeetCode - Combinations
常见组合题,按套路很容易做。class Solution {public: void _combine(vector >&res, int n, int cur, int k, int count,list &lst){ if(count==k){ vector tmp(lst.begin(),lst.end()); res.push_back(tmp);原创 2013-07-07 20:27:48 · 173 阅读 · 0 评论 -
LeetCode - Text Justification
一个字,烦。不难。每个人有每个人的解法。class Solution {public: string process(vector &tmp,int L,int len){ if(tmp.size()==1){ int space_num = L-tmp[0].length(); while(space_num--) tmp[0]+=" ";原创 2013-07-07 22:04:23 · 203 阅读 · 0 评论 -
LeetCode - Partition List
跟快排的partition类似。关于链表的题都不难,要的是细心,边界条件等考虑周全即可。/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} *原创 2013-06-21 13:13:55 · 182 阅读 · 0 评论 -
LeetCode - Remove Duplicates from Sorted List
删除链表中重复元素,略简单。/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:原创 2013-06-21 16:41:45 · 174 阅读 · 0 评论 -
LeetCode - Remove Duplicates from Sorted List II
删除链表中重复元素,和 I 的区别是如果有重复全部删除,一个不留。就多了点细节的东西,没什么难度。/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NUL原创 2013-06-21 16:58:30 · 185 阅读 · 0 评论 -
LeetCode - Sort Colors
计数排序,第一次扫描获得0,1,2的数量,第二次赋值。题目想只用一次扫描完成。先贴上two-pass。class Solution {public: void sortColors(int A[], int n) { int count[3]={0,0,0}; for(int i=0;i<n;i++) count[A[i]]++; for(int i=0;i原创 2013-06-21 20:15:20 · 215 阅读 · 0 评论 -
LeetCode - Sqrt(x)
有点类似二分搜索,每次判断中间数的平方,大于x则在左半部分继续查找,小于x则在有半部分。这样时间复杂度则为log(x),因为是32位int,所以也就是O(1)常数复杂度。需要注意的是对溢出的判断。class Solution {public: int _sqrt(int x, int start, int end){ if(start==end) return原创 2013-06-23 15:31:26 · 338 阅读 · 0 评论 -
LeetCode - Pow(x,n)
幂运算。如果单纯的循环+1计算肯定是不行的。n可以分解成以2为底的幂的多项式形式。比如n=40,可以分解成n = 32+8 = 2^5 + 2^3。 于是x^n = x^40 = x^32 + x^8。这样逐位分析n,就可逐渐获得最终的Pow(x,n)。需要注意的是当n为INT_MIN时,不能直接转化为-n,会溢出。class Solution {public:原创 2013-06-23 15:59:39 · 230 阅读 · 0 评论 -
LeetCode - Add Binary
把string先转化成vector可能会方便一些。class Solution {public: string addBinary(string a, string b) { vector res; vector c; vector d; for(int i=a.length()-1;i>=0;--i) a[i]=='1'?c.push_back(1):原创 2013-07-11 21:29:38 · 192 阅读 · 0 评论 -
LeetCode - Plus One
easy...class Solution {public: vector plusOne(vector &digits) { int len = digits.size(); vector res; int carry = 1; for(int i=digits.size()-1;i>=0;--i){ res.push_back((digits[i]+原创 2013-07-11 15:56:21 · 198 阅读 · 0 评论 -
LeetCode - Valid Number ***
刚开始首先想到的是用几个状态标志记录如点,符号,E等字符的出现,然后去判断,这样写出来的代码由无数if else构成,难读容易出错并且不好扩展。看了官方的有限状态机方法,发现非常简洁优雅,逻辑清晰易读,扩展方便。有限状态机需要构造一个转移矩阵,一旦矩阵构造完,剩下的逻辑代码就非常好写了。我这里用了10个状态。分别表示以下情况(正则表达式):0:[space]+1:(+|-)原创 2013-07-11 19:03:17 · 260 阅读 · 0 评论 -
LeetCode - Spiral Matrix *
旋转遍历矩阵。这题是有子问题的,所以用递归解法比较简洁易读。自然也可以用迭代解法,稍微烦一点。class Solution {public: void _spiralOrder(vector > &matrix, int i, int j, int m, int n, vector &res){ if(m<=0||n<=0) return; int p=原创 2013-07-11 22:09:36 · 192 阅读 · 0 评论 -
LeetCode - Anagrams
重构词的特点是 排序后相同。所以用一个hashmap,排序后为key,value为所有重构词的集合。最后扫面map,把集合元素数大于一的string输出到结果。class Solution {public: vector anagrams(vector &strs) { vector res; unordered_map >m; for(int i=0;i原创 2013-07-12 15:25:35 · 224 阅读 · 0 评论 -
LeetCode - Rotate Image
原地旋转,O(1)空间复杂度。一次旋转四个点。class Solution {public: void _rotate(vector > &matrix, int i, int j, int n){ if(n<=1) return; for(int q=j;q<j+n-1;++q){ int x1 = i, y1 = q; int x2 = y1原创 2013-07-12 16:02:17 · 197 阅读 · 0 评论 -
LeetCode - Jump Game
贪心算法,遍历数组,每次更新最大能跳到的地方。class Solution {public: bool canJump(int A[], int n) { int idx = 0; int i=0; while(idx<n-1 && i<=idx){ idx = max(idx,A[i]+i); ++i; } return idx>=n-1;原创 2013-07-13 16:15:52 · 180 阅读 · 0 评论 -
LeetCode - Unique Paths
递归版本:大数据超时。 int uniquePaths(int m, int n) { if(m<=0||n<=0) return 0; if(m==1||n==1) return 1; return uniquePaths(m-1,n)+uniquePaths(m,n-1); }原创 2013-07-13 20:35:07 · 210 阅读 · 0 评论 -
LeetCode - Insert Interval *
越简洁的代码往往越高效,越易读。这题一种简洁的解法是使用一个新的数组res保存结果,扫描intervals,newInterval可能在当前interval的左边,右边,或者相交。如果是前两种情况,则直接把newInterval放入res,如果是相交,则更新newInterval的左右边界,成为新的newInterval。bool变量has_put用于标识newInterval是否已经原创 2013-07-13 15:35:08 · 207 阅读 · 0 评论 -
LeetCode - Merge Intervals *
和Insert Intervals那题差不多。先排了个序,然后遍历intervals,将每一个Interval当做newInterval插入结果数组中。插入的时候只需要和结果数组中尾部的Interval比较即可(排序的目的)。/** * Definition for an interval. * struct Interval { * int start; *原创 2013-07-13 15:58:33 · 196 阅读 · 0 评论