编程练习:

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 放入数组,再排序后依次覆盖链表结点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值