1. 二叉树中两个结点的最近公共祖先结点
所以节点值为5和节点值为1的节点的最近公共祖先节点的节点值为3,所以对应的输出为3。
节点本身可以视为自己的祖先
int lowestCommonAncestor(TreeNode* root, int o1, int o2) {
if(!root)return -1;
if(root->val==o1||root->val==o2)return root->val;
//判断根节点,也可以是多次递归时判断的左右子树的根
int left=lowestCommonAncestor(root->left, o1, o2);
int right=lowestCommonAncestor(root->right, o1,o2);
if(left==-1)return right;
if(right==-1)return left;
return root->val;
}
解题思路:
- 寻找最近的根节点:根为空,返回-1
- 若寻找到两个结点分别在当前结点的左右子树上:返回当前根节点
- 在两棵子树的搜索中一定会返回left 和right 的值:
- 若寻找的两个结点只位于某一个子树,则在另一子树则找不到结点,返回-1:
-
- 在此情况下,两棵子树同时搜索两个结点,都在同一颗子树时,先搜索到的先返回
- 那么另一个未找到的结点一定在找到的结点下方
- 我们获取最近的根节点,则可以返回先找到的结点
- 当两棵子树都返回找到的结点值,那么当前两颗子树的根节点为所求
2. 阶乘后0的个数:
long long thenumberof0(long long n) {
long long int sum=0;
while(n)
{
sum+=(n/5);
n/=5;
}
return sum;
// write code here
}
3. 最长无重复子数组:
int maxLength(vector<int>& arr) {
unordered_map<int, int>map;
int i=0,j=0;
int max=0;
for(;i<=j&&j<arr.size();j++)
{
if(map.size()==0)
map[arr[j]]++;
else{
map[arr[j]]++;
if((map[arr[j]])>1)
{
while(map[arr[j]]>1)
map[arr[i++]]--;
}
}
if(max<(j-i+1))max=j-i+1;
}
return max;
}
- 使用unordered_map计数是否有重复,用左右指针删去重复元素
- max与左右指针的差比较大小 :max<(j-i+1)
注意:判断时map[]则已经初始化,加入map序列size++,用size()判断错误
- map.find(val)!=map.end(); //查找,与本题无关
4. 链表排序:
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
#include <endian.h>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类 the head node
* @return ListNode类
*/
ListNode*Sunx(ListNode*h1,ListNode*h2)
{
if(!h1)return h2;
if(!h2)return h1;
ListNode* h=new ListNode(0);
ListNode*head=h;
while(h1&&h2)
{
if(h1->val<=h2->val)
{
h->next=h1;
h1=h1->next;
}
else {
h->next=h2;
h2=h2->next;
}
h=h->next;
}
if(h1)
h->next=h1;
else if(h2)
h->next=h2;
return head->next;
}
ListNode* sortInList(ListNode* head) {
if(head==nullptr||head->next==nullptr)return head;
ListNode*l=head;
ListNode*m=head->next;
ListNode*r=head->next->next;
while(r&&r->next)
{
l=l->next;
m=m->next;
r=r->next->next;
}
l->next=nullptr;
return Sunx(sortInList(head),sortInList(m));
}
};
设置快中慢指针,
- 快指针一次两部走到队尾时,慢指针一次一步走到中间
- 以快指针当前在队尾或next是队尾作为判断依据,断开链表
- 慢指针走到第一段的结尾断开,慢指针next置空
- 则分为两端链表,head-> , mid->
放入排序链表,对每个结点进行比较
- return Sunx(sortInList(head),sortInList(m));
- 该函数的参数为结点划分的返回段节点,最终获取链表长度为1或0 终止return结果
- 在子参数的调用过程中再调用Sunx函数经行排序,获取子链表段的排序
- 将链表长度为0/1 传参给Sunx函数
- 参数为空返回另一个链表
- 参数不为空先将单个结点排序返回
- 获取有序链表后,继而对有序链表排序
- 返回当初标记的头结点的next指针
再简单的方法:直接把value 放入数组,再排序后依次覆盖链表结点