leetcode题解日练--2016.8.6
来源:互联网 发布:王者荣耀淘宝充值点卷 编辑:程序博客网 时间:2024/05/09 19:57
不给自己任何借口
今日题目:
❤1、二叉树最低公共祖先;
2、逆转链表II
今日摘录:
为着后来的回忆,小心着意地描绘你现在的图画
——冰心《冰心散文集》
236. Lowest Common Ancestor of a Binary Tree | Difficulty: Medium
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”
_______3______ / \ ___5__ ___1__ / \ / \ 6 _2 0 8 / \ 7 4
For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
相关题目:Lowest Common Ascestor of a BST
tag:树
题意:找一棵二叉树的两个节点的最低公共祖先。
思路:
1、首先回顾BST情况如何查找LCA?从根节点作为当前判断节点开始,判断当前节点是否同时小于两个待查节点(如果满足说明待LCA在当前节点的右子节点方向),如果同时大于待查找的节点说明LCA在当前节点的左子节点方向,如果均不满足则说明当前节点就是LCA。
但是当时满足了BST这一条件,也就是一个节点的左子节点一定比当前节点小,右子节点一定比当前节点大。但是去掉了这个条件之后我们需要怎么去做呢?还可以用类似的思路,从根节点开始,每次递归去查找我们的待查找节点,每一边第一次遇到任意一个待查找节点就停止继续查找,最后判断根节点的两边是否均有查找到,分情况讨论。
如果左右都找到了,就返回根节点
如果左边找到了而右边没找到,返回左节点,
如果右边找到而左边没找到,返回右节点,
不可能存在左右均没找到的情况
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { if (!root || root==p || root ==q) return root; TreeNode * left = lowestCommonAncestor(root->left,p,q); TreeNode * right = lowestCommonAncestor(root->right,p,q); if(left && right) return root; else if(left) return left; else return right; }};
结果:28ms
2、迭代版本,先去找到p和q这两个节点的位置并且记录下来他们的父节点,然后顺着这两条路径去找第一次相关的节点就是LCA。
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { stack<TreeNode*> nodes; unordered_map<TreeNode*,TreeNode*> parent; parent[root] = NULL; nodes.push(root); while(parent.find(p)==parent.end() || parent.find(q)==parent.end()) { TreeNode* node = nodes.top(); nodes.pop(); if(node->left) { nodes.push(node->left); parent[node->left] = node; } if(node->right) { nodes.push(node->right); parent[node->right] = node; } } set<TreeNode*>path; while(p) { path.insert(p); p = parent[p]; } while(q && path.find(q)==path.end()) { path.insert(q); q = parent[q]; } return q; }};
结果:64ms
92. Reverse Linked List II | Difficulty: Medium
Reverse a linked list from position m to n. Do it in-place and in one-pass.
For example:
Given 1->2->3->4->5->NULL, m = 2 and n = 4,
return 1->4->3->2->5->NULL.
Note:
Given m, n satisfy the following condition:
1 ≤ m ≤ n ≤ length of list.
相关题目:reverse Linked List
tag:链表
题意:反转链表中的一部分
思路:
1、一样的思路,只不过换成了首先找到逆转的头,然后逆转链表,这里面有一个比较关键的点就是是不是从头还是逆转,如果是那么新头是逆转链表的尾部元素,如果不是新头就是原来的头
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: ListNode* reverseBetween(ListNode* head, int m, int n) { int count = n-m+1; bool flag; if (m==1) flag = true; else flag = false; if(count==1) return head; ListNode* reverseHead = head; ListNode* before = head;; ListNode * prev = NULL; while(--m>0) { before = reverseHead; reverseHead = reverseHead->next; } ListNode* pNode = reverseHead; while(reverseHead && count-->0) { ListNode*next = reverseHead ->next; reverseHead ->next = prev; prev = reverseHead; reverseHead = next; } if(!flag) { before->next = prev; pNode->next = reverseHead; return head; } else { before->next = reverseHead; return prev; } }};
结果:4ms
第二次刷解法
首先找到反转之后链表的尾部(即reverseHead),它的前面一个是pre,目的是将pre指向反转链表的头部。当我们要逆转(1,3),其实相当于将2指向1,将3指向2,每次reverseHead指向的节点都是当前节点,取出一个当前节点之后就将reverseHead指向当前cur的下一个节点,做n-m次的反转操作之后节点逆序了,pre也指向了反转之后的头部。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: ListNode* reverseBetween(ListNode* head, int m, int n) { if(head==NULL||head->next==NULL||m==n) return head; n-=m; ListNode *preHead = new ListNode(0); preHead->next = head; ListNode*pre = preHead; while(--m) pre = pre->next; ListNode* reverseHead = pre->next; while(n--) { ListNode*cur = reverseHead->next; reverseHead->next = cur->next; cur->next = pre->next; pre->next = cur; } return preHead->next; }};
结果:4ms
- leetcode题解日练--2016.8.6
- leetcode题解日练--2016.8.1
- leetcode题解日练--2016.8.5
- leetcode题解日练--2016.8.8
- leetcode题解日练--2016.8.9
- leetcode题解日练--2016.8.10
- leetcode题解日练--2016.8.26
- leetcode题解日练--2016.8.27
- leetcode题解日练--2016.8.29
- leetcode题解日练--2016.8.30
- leetcode题解日练--2016.7.6
- leetcode题解日练--2016.6.16
- leetcode题解日练--2016.6.17
- leetcode题解日练--2016.6.19
- leetcode题解日练--2016.6.18
- leetcode题解日练--2016.6.20
- leetcode题解日练--2016.6.21
- leetcode题解日练--2016.6.22
- PyQt5教程-21-绘画
- 斯坦福第二章:最大似然函数
- HDU 1564 Play a game (博弈、找规律)
- WebView与iOS Native交互
- Educational Codeforces Round 8 E. Zbazi in Zeydabad(给你一个n*m矩阵,每个点可能是'.'或者'z',问有多少种Z子型(Z为一个正方形))
- leetcode题解日练--2016.8.6
- UIView详解之十:控件改变坐标系(convertRect:)
- MyEclipse 10 破解 run.bat 打不开 闪关的问题解决
- redhat快速安装mysql
- 算法-并查集-基于hdu1232
- 请注意写代码的习惯与态度(Java)
- android中跨进程通讯的4种方式
- A Simple Nim(多校,SG定理)
- Hibernate