05 2016 档案

摘要:中序遍历二叉搜索树,得到的是一个有序的结果,找出其中逆序的地方就可以了。如果逆序的地方相邻,只需把逆序的相换即可;如果不相邻,则需要找到第二个逆序对的 第二个元素再做交换。 定义两个指针p和q来指定需要交换的元素,指针pre记录当前结点的前驱结点,用来判断是否逆序。 void recoverTree 阅读全文
posted @ 2016-05-30 16:29 牧马人夏峥 阅读(92) 评论(0) 推荐(0) 编辑
摘要:采用广度优先遍历,一个变量记录层数,一个变量记录方向. void traverse(TreeNode *root, vector<vector<int>> result, int level, bool left_to_right) { if (!root)return; //如果进入下一层了,则r 阅读全文
posted @ 2016-05-30 14:57 牧马人夏峥 阅读(141) 评论(0) 推荐(0) 编辑
摘要:层序遍历,使用队列将每层压入,定义两个队列来区分不同的层。 vector<vector<int>> levelorderTraversal(TreeNode *root) { vector<vector<int>> result; vector<int>tmp; //通过两个queue来区分不同的层 阅读全文
posted @ 2016-05-28 16:27 牧马人夏峥 阅读(110) 评论(0) 推荐(0) 编辑
摘要:后序遍历,比先序和中序都要复杂。访问一个结点前,需要先判断其右孩子是否被访问过。如果是,则可以访问该结点;否则,需要先处理右子树。 vector<int> postorderTraversal(TreeNode *root) { vector<int> result; stack<TreeNode 阅读全文
posted @ 2016-05-28 16:10 牧马人夏峥 阅读(150) 评论(0) 推荐(0) 编辑
摘要:树的中序遍历。先不断压入左结点至末尾,再访问,再压入右结点。注意和先序遍历的比较 vector<int> inorderTraversal(TreeNode *root) { vector<int> result; stack<TreeNode *>s; TreeNode *p = root; wh 阅读全文
posted @ 2016-05-28 15:29 牧马人夏峥 阅读(96) 评论(0) 推荐(0) 编辑
摘要:树的先序遍历。定义一个栈,先压入中间结点并访问,然后依次压入右、左结点并访问。 vector<int> preorderTraversal(TreeNode *root) { vector<int> result; stack<TreeNode *>s; TreeNode *p; p = root; 阅读全文
posted @ 2016-05-28 15:05 牧马人夏峥 阅读(114) 评论(0) 推荐(0) 编辑
摘要:很简单的一道题,定义一个栈保留操作数,遇操作符则弹出运算即可。 bool isOperator(string &op) { //注意用法 return op.size() == 1 && string("+-*/").find(op) != string::npos; } int evalRPN(v 阅读全文
posted @ 2016-05-28 14:44 牧马人夏峥 阅读(126) 评论(0) 推荐(0) 编辑
摘要:又是一道构思巧妙的题,暴力求解复杂度太高,通过构造一个递增栈来解决:如果当前元素小于栈顶元素,则说明栈内已经构成一个 递增栈,则分别计算以每个元素为最低值的面积;反之,则入栈。 int largestRect(vector<int> &height) { stack<int> s;//定义一个单调递 阅读全文
posted @ 2016-05-28 14:22 牧马人夏峥 阅读(175) 评论(0) 推荐(0) 编辑
摘要:有一定的难度。用堆栈记录下所有左符的位置,用变量记录下孤立右符的位置。 int longestValidParentheses(const string& s) { stack<int>lefts;//将左符对应的位置保留 int last;//记录孤立的右符位置 int max_len = 0;/ 阅读全文
posted @ 2016-05-26 16:08 牧马人夏峥 阅读(171) 评论(0) 推荐(0) 编辑
摘要:做法很巧妙。分成左右两个对应的部分,遇到左半部分则入栈,遇到右半部分则判断对应的左半部分是否在栈顶。注意最后要判断堆栈是否为空。 bool isValid(const string& s) { string left = "([{"; string right = ")]}"; stack<char 阅读全文
posted @ 2016-05-26 15:34 牧马人夏峥 阅读(115) 评论(0) 推荐(0) 编辑
摘要:扫描每个WORD的长度并记录即可。 int lengthOfLast(const char *s) { //扫描统计每个word的长度 int len = 0; while (*s) { if (*s++ != ' ')//注意不管是否满足s都要++ len++; else if (*s && *s 阅读全文
posted @ 2016-05-26 09:24 牧马人夏峥 阅读(121) 评论(0) 推荐(0) 编辑
摘要:主要看//之间的内容:如果是仍是/,或者是.,则忽略;如果是..,则弹出;否则压入堆栈。最后根据堆栈的内容进行输出。 string simplifyPath(string const& path) { vector<string> dirs; for (auto i = path.begin(); 阅读全文
posted @ 2016-05-26 09:09 牧马人夏峥 阅读(160) 评论(0) 推荐(0) 编辑
摘要:回文构词法,将字母顺序打乱。可将字母重新排序,若它们相等,则属于同一组anagrams。 可通过hashmap来做,将排序后的字母作为key。注意后面取hashmap值时的做法。 vector<string> anagrams(vector<string> &strs) { unordered_ma 阅读全文
posted @ 2016-05-26 08:28 牧马人夏峥 阅读(107) 评论(0) 推荐(0) 编辑
摘要:很有意思的一道题,不好想啊。 string getNext(string &s) { char start = s[0]; int count = 0; stringstream ss; for (int i = 0; i < s.size(); i++) { if (start == s[i]) 阅读全文
posted @ 2016-05-25 18:26 牧马人夏峥 阅读(117) 评论(0) 推荐(0) 编辑
摘要:这题实现起来还是挺麻烦的,就偷懒使用下库函数strtod()。第二个参数表示字符中不是数字的地方,如果后面是空格,则认为其仍是数字,否则不是。 bool isNumber(char *s) { char *endptr; strtod(s, &endptr); if (endptr == s)ret 阅读全文
posted @ 2016-05-25 17:20 牧马人夏峥 阅读(129) 评论(0) 推荐(0) 编辑
摘要:在一组字符串中找到最长的子串。采用纵向匹配,遇到第一个不匹配的停止。 string longestComPrefix(vector<string> &strs) { if (strs.empty())return " "; //纵向比较 for (int idx = 0; idx < strs[0] 阅读全文
posted @ 2016-05-25 17:02 牧马人夏峥 阅读(101) 评论(0) 推荐(0) 编辑
摘要:跟上题类似,主要考虑‘*’的匹配问题。如果遇到‘*’,则跳过继续匹配,如果不匹配,则s++,重新扫描。 bool isMatch2(const char *s, const char *p) { if (*p == '*') { while (*p == '*')p++; if (*p == '\0 阅读全文
posted @ 2016-05-25 16:45 牧马人夏峥 阅读(120) 评论(0) 推荐(0) 编辑
摘要:正则表达式的匹配,还是挺难的。可根据下一个字符是不是*分为两种情况处理,需要考虑多种情况。 bool isMatch(const char *s, const char *p) { if (*p == '\0')return *s == '\0'; //如果下一个不是*(*可表示前一个字符的数量) 阅读全文
posted @ 2016-05-24 16:20 牧马人夏峥 阅读(135) 评论(0) 推荐(0) 编辑
摘要:很经典的一道题,最长回文子串,有多种方法。 首先介绍的一种方法是从中间向两边展开。注意区分aba和abba型的回文串;如果当前最长的子串已经当于两边中最长的子串了,则无需再去判断。 //从中间向两边展开 string expandAroundCenter(string s, int c1, int 阅读全文
posted @ 2016-05-24 15:07 牧马人夏峥 阅读(168) 评论(0) 推荐(0) 编辑
摘要:比较简单,细节:先将字符串翻转,注意进位。 string addBinary(string a, string b) { string result; int len = a.size() > b.size() ? a.size() : b.size(); reverse(a.begin(), a. 阅读全文
posted @ 2016-05-23 13:10 牧马人夏峥 阅读(112) 评论(0) 推荐(0) 编辑
摘要:字符串转为数字,细节题。要考虑空格、正负号,当转化的数字超过最大或最小是怎么办。 int atoi(char *str) { int len = strlen(str); int sign = 1; int num = 0; int i = 0; while (str[i] == ' '&& i < 阅读全文
posted @ 2016-05-23 12:53 牧马人夏峥 阅读(268) 评论(0) 推荐(0) 编辑
摘要:字符串的匹配,返回匹配开始的位置,直接用暴力方式求解。为了更快的匹配,定义一个指针表示待匹配的字符串的长度,当长度不足时,可 直接停止匹配。 char *strStr(char *haystack, char*needle) { char* p1; char* p2; char* p1_advanc 阅读全文
posted @ 2016-05-23 12:30 牧马人夏峥 阅读(103) 评论(0) 推荐(0) 编辑
摘要:现在开始进入字符串系列。 判断回文串的。首尾各定义一个指针,然后相比较。难点在于如何提出非字母数字的字符。 bool isValidPalind(string s) { //转为小写,注意这个函数的用法 transform(s.begin(), s.end(), s.begin(), ::towlo 阅读全文
posted @ 2016-05-23 11:21 牧马人夏峥 阅读(92) 评论(0) 推荐(0) 编辑
摘要:很实际的一道题。定义一个双向链表list,方便插入和删除;定义一个哈希表,方便查找。 具体的,哈希表存放每个结点的key和它对应的结点的地址;访问结点时,如果结点存在,则将其交换到头部,同是更新哈希表中的地址; 插入结点时,首先判断capacity是否达到了上限,如果是则在链表和哈希表中删除该结点; 阅读全文
posted @ 2016-05-23 11:03 牧马人夏峥 阅读(153) 评论(0) 推荐(0) 编辑
摘要:找到中间结点,将后半部分反转接入即可。 ListNode *reoderList(ListNode* head) { if (head == nullptr || head->next == nullptr)return head; //找到中间结点的方法很巧妙 ListNode *slow = h 阅读全文
posted @ 2016-05-21 16:14 牧马人夏峥 阅读(128) 评论(0) 推荐(0) 编辑
摘要:两个思路,一是用哈希表记录每个结点是还被访问过;二是定义两个快、慢指针,如果存在环的话,两个指针必定会在某位结点相遇。 bool linkListNode(ListNode *head) { ListNode *fast=head, *slow=head; while (fast && fast-> 阅读全文
posted @ 2016-05-21 16:02 牧马人夏峥 阅读(97) 评论(0) 推荐(0) 编辑
摘要:深拷贝一个链表,不同的是这个链表有个额外的随机指针。参考:http://blog.csdn.net/ljiabin/article/details/39054999 做法非常的巧妙,分成三步,一是新建结点,并放在旧结点之后;二是修改新结点的random指针;三是将新旧链表断开。 RandomList 阅读全文
posted @ 2016-05-21 15:29 牧马人夏峥 阅读(107) 评论(0) 推荐(0) 编辑
摘要:这题有点繁琐,在更新指针时很容易出错。 ListNode *reverseKGroup(ListNode *head, int k) { if (head == nullptr || head->next == nullptr || k < 2)return head; ListNode dummy 阅读全文
posted @ 2016-05-19 15:52 牧马人夏峥 阅读(155) 评论(0) 推荐(0) 编辑
摘要:不允许通过值来交换,在更新指针时需要小心。 ListNode *swapNodes(ListNode* head) { ListNode dummy(-1); dummy.next = head; for (ListNode *prev = &dummy, *cur = prev->next, *p 阅读全文
posted @ 2016-05-19 14:48 牧马人夏峥 阅读(115) 评论(0) 推荐(0) 编辑
摘要:这题比较简单,方法有很多。其中一种比较有意思的做法是设置两个指针,一个先走n步,然后再一起走。一个到了末尾,另一个也就确定了要删除元素的位置。 ListNode *removeNthFromEnd(ListNode *head, int n) { ListNode dummy{-1, head}; 阅读全文
posted @ 2016-05-19 14:27 牧马人夏峥 阅读(102) 评论(0) 推荐(0) 编辑
摘要:这题我的第一想法是用头插法,但实际上并不好做,因为每次都需要遍历最后一个。更简单的做法是将其连成环,找到相应的位置重新设头结点和尾结点。这过 有很多细节需要注意,比如K有可能是大于链表长度的,如何重新设置K等都要注意。 ListNode *rotateList(ListNode *head, int 阅读全文
posted @ 2016-05-19 14:06 牧马人夏峥 阅读(114) 评论(0) 推荐(0) 编辑
摘要:很简单的一题,需要注意的是如果某结点重复了记得将其删除。 ListNode *deleteDuplicates(ListNode *head) { if (head == nullptr) return nullptr; ListNode *prev = head; for (ListNode *c 阅读全文
posted @ 2016-05-18 15:34 牧马人夏峥 阅读(124) 评论(0) 推荐(0) 编辑
摘要:思路就是定义两个链表,一个放大的,一个放小的,最后将两个连起来,注意细节问题。 ListNode *partionList(ListNode *head, int value) { ListNode left_dummy(-1); ListNode right_dummy(-1); auto lef 阅读全文
posted @ 2016-05-18 15:15 牧马人夏峥 阅读(100) 评论(0) 推荐(0) 编辑
摘要:这题用需要非常细心,用头插法移动需要考虑先移动哪个,只需三个指针即可。 ListNode *reverseList(ListNode *head, int m, int n) { ListNode dummy(-1); dummy.next = head; ListNode *prev = &dum 阅读全文
posted @ 2016-05-18 14:45 牧马人夏峥 阅读(96) 评论(0) 推荐(0) 编辑
摘要:这题并不难,但需要注意细节。 ListNode* addTwo(ListNode *l1, ListNode *l2) { ListNode dummy(-1); int carry = 0; ListNode *prev = &dummy; for (ListNode *pa = l1, *pb 阅读全文
posted @ 2016-05-18 14:00 牧马人夏峥 阅读(79) 评论(0) 推荐(0) 编辑
摘要:看见这题我的第一反应是用哈希来做,不过更简洁的做法是用异或来处理,只要是偶数个都为0(0和任意数异或仍为数本身)。 int singleNumber(int A[], int n) { int x = 0; for (int i = 0; i < n; i++) x ^= A[i]; return 阅读全文
posted @ 2016-05-17 15:14 牧马人夏峥 阅读(92) 评论(0) 推荐(0) 编辑
摘要:这题的思路很巧妙,分两遍扫描,将元素分别和左右元素相比较。 int candy(vector<int> &rattings) { int n = rattings.size(); vector<int> incrment(n); int inc = 1; //和左边比较 for (int i = 1 阅读全文
posted @ 2016-05-17 15:02 牧马人夏峥 阅读(119) 评论(0) 推荐(0) 编辑
摘要:这题的思路很巧妙,用两个变量,一个变量衡量当前指针是否有效,一个衡量整个数组是否有解,需要好好体会。 int gasStation(vector<int> &gas, vector<int> &cost) { int total = 0; int j; int sum = 0; for (int i 阅读全文
posted @ 2016-05-16 14:40 牧马人夏峥 阅读(90) 评论(0) 推荐(0) 编辑
摘要:设置两个布尔数组,记录行和列是否存在0。需要注意的是如何将行或列设为0. void setZeros(vector<vector<int>> &matrix) { int m = matrix.size(); int n = matrix[0].size(); vector<bool>row(m, 阅读全文
posted @ 2016-05-16 14:21 牧马人夏峥 阅读(118) 评论(0) 推荐(0) 编辑
摘要:这题需要注意的是最后的进位 vector<int> plusOne(vector<int>& nums,int num) { add(nums, num); } void add(vector<int> &nums, int num) { int c = num; for (auto it = nu 阅读全文
posted @ 2016-05-16 13:21 牧马人夏峥 阅读(102) 评论(0) 推荐(0) 编辑
摘要:这题需要搞清楚矩阵元素的位置关系,尤其是副对角线元素,沿着副对角线元素 void rotateImage(vector<vector<int>> &matrix) { int n = matrix.size(); //沿着副对角线翻转 for (int i = 0; i < n;i++) for ( 阅读全文
posted @ 2016-05-15 20:47 牧马人夏峥 阅读(152) 评论(0) 推荐(0) 编辑
摘要:这题不太好想。可以先扫描找到最高的柱子,然后分别处理两边:记录下当前的局部最高点,如果当前点小于局部最高点,加上, 反则,替换当前点为局部最高点。 int trapWater(int A[], int n) { int peak = 0; int max = 0; int water = 0; fo 阅读全文
posted @ 2016-05-15 20:15 牧马人夏峥 阅读(303) 评论(0) 推荐(0) 编辑
摘要:判断行、列、九宫格内数字是否重复。 按照行、列、九宫格进行检查即可。 bool validSudoku(const vector<vector<char>>& board) { bool used[9]; for (int i = 0; i < 9; i++) { fill(used, used + 阅读全文
posted @ 2016-05-15 17:05 牧马人夏峥 阅读(181) 评论(0) 推荐(0) 编辑
摘要:首先是next permutation的算法的描述和分析如下: 这题一是要知道思路,编程中注意STL的用法 void nextPermutaion(vector<int> &num) { next_permutation(num.begin(), num.end()); } private: tem 阅读全文
posted @ 2016-05-15 15:34 牧马人夏峥 阅读(229) 评论(0) 推荐(0) 编辑
摘要:第一题是Two Sum 同样是用哈希表来做,需要注意的是在查打gap是要排除本身。比如target为4,有一个值为2,gap同样为2。 vector<int> twoSum(vector<int> &num, int target) { unordered_map<int, int> mapping 阅读全文
posted @ 2016-05-14 15:02 牧马人夏峥 阅读(225) 评论(0) 推荐(0) 编辑
摘要:这题要仔细体会下哈希表的用法,要注意的是数组本身是无序的,因此需要向左右进行扩张。 另外这个思路可以进行聚类,把连续的标记为一类。 int longestConsecutive(const vector<int> &num) { unordered_map<int, bool> used; for 阅读全文
posted @ 2016-05-14 14:22 牧马人夏峥 阅读(131) 评论(0) 推荐(0) 编辑
摘要:找两个排好序的数组的中间值,实际上可以扩展为寻找第k大的数组值。 参考下面的思路,非常的清晰: 代码: double findMedianofTwoSortArrays(int A[], int B[], int m, int n) { int total = m + n; //判断序列长度的奇偶, 阅读全文
posted @ 2016-05-14 13:31 牧马人夏峥 阅读(133) 评论(0) 推荐(0) 编辑
摘要:描述 Follow up for ”Search in Rotated Sorted Array”: What if duplicates are allowed? Would this affect the run-time complexity? How and why? Write a fun 阅读全文
posted @ 2016-05-01 21:34 牧马人夏峥 阅读(127) 评论(0) 推荐(0) 编辑
摘要:描述 Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). You are given a target 阅读全文
posted @ 2016-05-01 21:10 牧马人夏峥 阅读(128) 评论(0) 推荐(0) 编辑
摘要:描述 Follow up for ”Remove Duplicates”: What if duplicates are allowed at most twice? For example, Given sorted array A = [1,1,1,2,2,3], Your function s 阅读全文
posted @ 2016-05-01 20:30 牧马人夏峥 阅读(119) 评论(0) 推荐(0) 编辑
摘要:删除数组中的重复元素并返回新数组的个数 思路:保留不同的元素即可。 阅读全文
posted @ 2016-05-01 19:56 牧马人夏峥 阅读(115) 评论(0) 推荐(0) 编辑

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