【数据结构与算法】双指针(二)

使用双指针


剑指 Offer 25. 合并两个排序的链表

https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/submissions/

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    //有空链表返回不空链表即可
    if(l1==null || l2==null){
        return l1!=null?l1:l2;
    }

    ListNode dummy = new ListNode(0);
    ListNode tmp = dummy;
    while(l1!=null && l2!=null){
        if(l1.val<=l2.val){
            tmp.next=l1;
            l1=l1.next;
        }else{
            tmp.next=l2;
            l2=l2.next;
        }
        tmp=tmp.next;
    }
    //l1为空或l2为空
    tmp.next=(l1==null?l2:l1);
    return dummy.next;
}

两数相加

https://leetcode-cn.com/problems/add-two-numbers/

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    int carry=0;
    ListNode head = new ListNode(-1), cur=head;
    while(l1!=null || l2!=null){
        int n1 = l1==null? 0:l1.val;
        int n2 = l2==null? 0:l2.val;
        //计算节点相加后的结果
        int sum =n1+n2+carry;
        //更新进位
        carry = sum/10;
        //结果储存在新链表中
        cur.next=new ListNode(sum%10);
        cur=cur.next;
        //更新双指针
        if(l1!=null) l1=l1.next;
        if(l2!=null) l2=l2.next;
    }
    if(carry>0){
        cur.next=new ListNode(carry);
    }
    return head.next;
}

复杂度分析

时间复杂度: O ( m a x ( m , n ) ) O(max(m,n)) O(max(m,n)),其中 m,n 为两个链表的长度。我们要遍历两个链表的全部位置,而处理每个位置只需要 O ( 1 ) O(1) O(1) 的时间。
空间复杂度: O ( m a x ( m , n ) ) O(max(m,n)) O(max(m,n))。答案链表的长度最多为较长链表的长度 +1。

个人遇到的问题:
1、处理链表节点为null的方式:int n1 = l1==null? 0:l1.val
2、对于整型数据 sum/10 为向下取整

26. 删除排序数组中的重复项

https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/

public int removeDuplicates(int[] nums) {
    if(nums.length==0) return 0;
    //使用快慢指针
    //由于数组已经排序,所以重复的元素连在一起
    int slow=0, fast=0;
    while(fast<nums.length){
        //当找到新元素后,用nums[0...slow]维护
        if(nums[slow]!=nums[fast]){
            slow++;
            nums[slow]=nums[fast];
        }
        fast++;
    }
    return slow+1;
}

430. 扁平化多级双向链表(中)

https://leetcode-cn.com/problems/flatten-a-multilevel-doubly-linked-list/
在这里插入图片描述

 1---2---3---4---5---6--NULL
         |
         7---8---9---10--NULL
             |
             11--12--NULL

可转化为二叉树的先序遍历求解

public Node flatten(Node head) {
    if (head==null) return null;

    Node dummy=new Node(-1,null,head,null);
    //定义递归函数,返回去序列化后的尾部指针(此处不需要返回值)
    flatten_dfs(dummy, head);

    dummy.next.prev=null;
    return dummy.next;
}

public Node flatten_dfs(Node pre, Node cur){
    if(cur==null) return pre;

    //前序遍历
    pre.next=cur;  //目的是将子链表的尾节点与下一节点链接
    cur.prev=pre;

    Node curNext=cur.next;
    Node tail = flatten_dfs(cur,cur.child); //cur.child看做左子树
    cur.child = null;

    return flatten_dfs(tail,curNext); //cur.next看做右子树
}

二叉树递归遍历框架

void traverse(TreeNode root) {
    // 前序遍历
    traverse(root.left)
    // 中序遍历
    traverse(root.right)
    // 后序遍历
}

https://mp.weixin.qq.com/s/ZYaXOSVM3YBIeRWm7E_jcQ

138. 复制带随机指针的链表(中)

https://leetcode-cn.com/leetbook/read/linked-list/fdi26/

对链表进行一次遍历操作,并用哈希映射来储存辅助信息

HashMap<Node,Node> map = new HashMap();
public Node copyRandomList(Node head) {
    //方法一,使用哈希Map记录节点是否被深拷贝
    if (head==null) return null;

    Node oldhead=head;
    Node newhead=new Node(head.val,null,null);
    this.map.put(head,newhead); 
    //进行迭代
    while(oldhead!=null){
        newhead.random = this.getClonedNode(oldhead.random);
        newhead.next = this.getClonedNode(oldhead.next);

        newhead=newhead.next;
        oldhead=oldhead.next;
    }
    return this.map.get(head);   
}
public Node getClonedNode(Node node){
    //返回一个拷贝节点,并记录在哈希表中
    if(node==null) return null;
    if(this.map.containsKey(node)){
        return this.map.get(node);
    } else {
        this.map.put(node, new Node(node.val,null,null));
    } return this.map.get(node);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值