牛客面试必刷TOP101--链表篇(1)

BM1 反转链表

public class Solution {
    public ListNode ReverseList(ListNode head) {
        ListNode cur = head;
        ListNode p = null;
        while (cur != null) {
            ListNode n = cur.next;
            cur.next = p;
            p = cur;
            cur = n;
        }
        return p;
    }
    }

 描述:定义三个ListNode类型的变量,分别为curr=head,p,n,p为curr的前一个节点,n为curr的后一个节点,如果curr不为空,curr.next = p;然后curr,p,n分别往前走;如果curr==null了,那么p即为此链表最后一个节点,即反转链表的头节点,返回p即可

BM2 链表内指定区间反转

public class Solution {
    public ListNode reverseBetween(ListNode head, int m, int n) {
        if(head==null)
            return null;
        int diff=n-m;
        ListNode headPre=new ListNode(0);
        headPre.next=head;
        ListNode slow=head;
        ListNode slowPre=headPre;
        for(int i=1;i<m;i++){
            slowPre=slow;
            slow=slow.next;
        }
        for(int j=0;j<diff;j++){
            ListNode temp=slow.next;
            slow.next=temp.next;
            temp.next=slowPre.next;
            slowPre.next=temp;
        } 
        return headPre.next;
    }
}

描述:要翻转m到n的n-m个链表节点,首先定义slow指向head,slowPre.next指向slow,定义deff=n-m;slow向前走直到走到下标为m的链表节点,此时slowPre记录断开位置,每次翻转temp记录翻转链表的头结点slowPre连接temp,slow记载尾节点且连接后续节点,最后返回headPre。next即头结点即可

BM3 链表中的节点每k个一组翻转

public ListNode reverseKGroup (ListNode head, int k) {//每k个翻转一次
        // write code here
        ListNode newhead = head;
        ListNode preNode = head;
        int count = 1;
        while(newhead != null){
            newhead = newhead.next;
            if(newhead!=null){
                count++;
            }
        }
        if(count<k||head ==null||head.next==null){
            return head;
        }
        count = 1;
        newhead = head;
        ListNode nextNode = newhead.next;
        newhead.next = null;
        while(count<k){
            newhead = nextNode;
            nextNode = nextNode.next;
            newhead.next = preNode;
            preNode = newhead;
            count++;
        }
        head.next=reverseKGroup(nextNode,k);
        return newhead;
    }

描述:第一个while求后面的节点个数,如果小于k说明不用翻转,直接返回head,count重新置1,

如果第二个while内翻转特定链表,再调用递归,将每k个翻转问题转变成多个翻转链表指定区间的问题,即可求解

BM4 合并两个排序的链表

public class Solution {
    public ListNode Merge(ListNode list1,ListNode list2) {
        ListNode ls = new ListNode(-1);
        ListNode head =ls;
        while(list1!=null&&list2!=null){
            if(list1.val>list2.val){
                ls.next =list2;
                list2 = list2.next;
                ls = ls.next;
            }else{
                ls.next = list1;
                list1 = list1.next;
                ls = ls.next;
            }
        }
        if(list1!=null){
            ls.next = list1;
        }
        if(list2!=null){
            ls.next = list2;
        }
        return head.next;
    }
}

 描述:定义一个新的节点ls和head,head记录新链表头结点位置,ls记录尾节点位置,如果list1的值大于list2的值,则让ls.next指向list2,list2往后走,ls往后走,反之list1往后走,ls往后走。如果list1==null则把list2加到ls后面,反之就把list1加到ls后面

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值