【算法总结】LinkedList 链表问题

  1. 描述:
    链表问题主要是针对链表的操作,主要是链表的merge, reverse, insert/delete/in-place, Fast & Slow pointer 的操作组合起来使用的各种变形题。链表分为单向链表和双向链表(double linkedList).
  2. 例题:
  3. 解决方法 & 复杂度 & 代码:
    • Dummy node: 
      Dummy node一般是new node(0), dummy 指向第一个node, 这样无论第一个Node怎样变化,只要返回dummy的下一个就可以了。
	    Node dummy = new Node(0);
	    dummy.next = head;

    • Reverse:
      做reverse操作的时候,是把下一个指针指向当前,一直到最后。时间:O(n) , 空间:O(1)
                   

public ListNode reverse(ListNode head){
	    	ListNode newHead = null;
	    	while(head != null){
	    		ListNode next = head.next;
	    		head.next = newHead;
	    		newHead = head;
	    		head = next;
	    	}
	    	return newHead;
	    }

    • Merge & Divide:
      new一个新的head 作为一个list, 按照特定条件将两个List的node一个个append到新的head上。可以见下代码中的mergeList()方法。时间O(n), 空间O(1)
    • Fast & Slow pointer
      一个快指针,一个慢指针,从头出发,快指针如果两倍速度走,等快指针到结束点时,慢指针到终点。往往用来找中点,也可以找1/3, 1/4点等。
ListNode fast = head;
        ListNode slow = head;
        while(fast.next != null && fast.next.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }
        //slow 为后一半list的头
        ListNode mid = slow.next;


    • Merge k sorted list (merge sort)
      每两个list合并为一个List, 再与其他合并后的List再合并。
              


public class Solution {
    /**
     * @param lists: a list of ListNode
     * @return: The head of one sorted list.
     */
    public ListNode mergeKLists(List<ListNode> lists) {  
        // write your code here
        if(lists==null || lists.size()==0){
            return null;
        }
        return mergeLists(lists, 0, lists.size()-1);
        
    }
    private ListNode mergeLists(List<ListNode> lists, int l, int r){
        if(l==r){
            return lists.get(l);
        }
        int m = (l+r)/2;
        ListNode left = mergeLists(lists, l, m);
        ListNode right = mergeLists(lists, m+1, r);
        return merge(left, right);
    }
    private ListNode merge(ListNode left, ListNode right){
        ListNode dummy = new ListNode(0);
        ListNode pre = dummy;
        while(left!=null && right!=null){
            if(left.val<right.val){
                pre.next = left;
                left = left.next;
            }else{
                pre.next = right;
                right = right.next;
            }
            pre = pre.next;
        }
        if(left!=null){
            pre.next = left;
        }
        if(right !=null){
            pre.next = right;
        }
        return dummy.next;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值