链表 -- 算法

链表

 

链表实现栈

    在链表头部插入和删除节点时间复杂度O(1),所以可以构建栈。

    对链表增加一个tail指针,可以构造队列。

 

removeElements

 

反转链表

反转链表关键点是需要3个指针:pre、cur和next。最基本的接口有两个:反转全部链表反转某一个节点后面的n个节点

 

// 反转第from个到第to个节点
ListNode reverseBetween(ListNode head, int from, int to){
    ListNode dummy = new ListNode();
    dummy.next = head;
    ListNode pre = dummy;  // 最终落到第from个节点的前一个
    while(--from > 0) pre = pre.next; // pre移动from-1次
    ListNode post = null;  // 最终落到第to个节点的下一个节点
    ListNode tail = pre.next;  // 反转后反转部分尾部节点
    pre.next = reverse(pre.next, to-from, post);
    tail.next = post;
    return dummy.next;
}

// 反转 head 后面 index 个节点
// 并将最后一个节点的下一个节点保存到post中
// 返回反转后的头结点,即原来的尾结点
ListNode reverse(ListNode head, int index, ListNode post){
    if(index==0){
        post = head.next;
        return head;
    }
    
    ListNode tail = head.next;
    ListNode ret = reverse(head.next, index-1, post);
    tail.next = head;
    return ret;
}
// 边界条件考虑的比较齐全的写法,无需dummyNode
ListNode reversePart(ListNode head, int from, int to){
    if(head==null || from >= to) return head;
    int len=0;
    ListNode fPre=null, tPost=null;
    ListNode node1=head;
    while(node1!=null){
        len++;
        fPre = len==from-1 ? node1 : fPre;
        tPost = len==to+1 ? node1 : tPost;
        node1 = node1.next;
    }
    if(from>to || from < 1 || to > len) 
        return head;
    // 反转部分的第一个节点
    node1 = fPre==null ? head : fPre.next;
    node1.next = tPost; // 提前指向tPost
    ListNode node2 = node1.next;
    while(node2!=tPost){
        ListNode next = node2;
        node2.next = node1;
        node1 = node2;
        node2 = next;
    }
    // node1变为了部分链表反转后的第一个
    if(fPre!=null){
        fPre.next = node1;
        return head;
    }
    return node1;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值