链表反转面试题

leetcode92指定区间反转

头插法:

代码:

 public static ListNode reverseBetween2(ListNode head, int left, int right) {
        // 设置 dummyNode 是这一类问题的一般做法
        ListNode dummyNode=new ListNode(-1);
        dummyNode.next=head;
        ListNode pre=dummyNode;
        for (int i=0;i<left-1;i++){
            pre=pre.next;
        }
        ListNode cur=pre.next;
        for (int i=0;i<right-left;i++){
            ListNode next=cur.next;
            cur.next=next.next;
            next.next=pre.next;
            pre.next=next;
        }
        return dummyNode.next;
    }

穿针引线法

找到指定片段,然后断开反转再接上

代码:

/**
     * 方法1:穿针引线法
     *
     * @param head
     * @param left
     * @param right
     * @return
     */
    public static ListNode reverseBetween(ListNode head, int left, int right) {
        // 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论
        ListNode dummyHead=new ListNode(-1);
        dummyHead.next=head;
        ListNode pre=dummyHead,l=head;
        // 第 1 步:从虚拟头节点走 left - 1 步,来到 left 节点的前一个节点
        // 建议写在 for 循环里,语义清晰
        for (int i=0;i<left-1;i++){
            l=l.next;
            pre=pre.next;
        }
        // 第 2 步:从 pre 再走 right - left + 1 步,来到 right 节点,next再走一步
        ListNode next=pre,r=pre;
        for (int i=0;i<right-left+1;i++){
            r=r.next;
            next=next.next;
        }
        next=next.next;
        // 第 3 步:切断出一个子链表(截取链表)
        pre.next=null;
        r.next=null;
        // 第 4 步:同第 206 题,反转链表的子区间
        ListNode newhead=reverseList(l);
        // 第 5 步:接回到原来的链表中
        pre.next=newhead;
        l.next=next;
        return dummyHead.next;
    }

    /**
     * 基本的反转方法
     *
     * @param head
     * @return
     */
    public static ListNode  reverseList(ListNode head) {
        ListNode pre=head;
        ListNode cur=head.next;
        while (cur!=null){
            ListNode next=cur.next;
            cur.next=pre;
            pre=cur;
            cur=next;
        }
        return pre;
    }

leetcode24两两交换表中节点

 public static  ListNode swapPairs(ListNode head) {
        ListNode dummyHead=new ListNode(-1);
        dummyHead.next=head;
        ListNode cur=dummyHead;
        while (cur.next!=null&&cur.next.next!=null){
            ListNode node1=cur.next,node2=cur.next.next;
            cur.next=node2;
            node1.next=node2.next;
            node2.next=node1;
            cur=node1;
        }
        return dummyHead.next;

    }

 链表加法

       leetcode369链表加一

plus是进位,addr是个位加一

 public static ListNode plusOne(ListNode head) {
        Stack<Integer> stack=new Stack<>();
        ListNode cur=head;
        while (cur!=null){
            stack.push(cur.val);
            cur=cur.next;
        }
        ListNode dummyHead=new ListNode(-1);
        int plus=0,addr=1;
        while (!stack.isEmpty()||plus>0){
            int digit=stack.empty()?0:stack.pop();
            int sum=digit+addr+plus;
            plus=sum>=10?1:0;
            sum=sum>=10?sum-10:sum;
            ListNode temp=new ListNode(sum);
            temp.next=dummyHead.next;
            dummyHead.next=temp;
            addr=0;
        }
        return dummyHead.next;
    }

leetcode445链表加法

用栈实现:

/**
     * 通过栈来实现
     *
     * @param l1
     * @param l2
     * @return
     */
    public static ListNode addInListByStack(ListNode l1, ListNode l2) {
        Stack<Integer> st1 = new Stack<>();
        Stack<Integer> st2 = new Stack<>();
        while (l1 !=null){
            st1.push(l1.val);
            l1 = l1.next;
        }
        while (l2 !=null){
            st2.push(l2.val);
            l2 = l2.next;
        }
        ListNode newHead=new ListNode(-1);
        int carry=0;
        while (!st1.isEmpty()||!st2.isEmpty()||carry!=0){
            int a,b;
            a=st1.isEmpty()?0:st1.pop();
            b=st2.isEmpty()?0:st2.pop();
            int sum=a+b+carry;
            int ans=sum%10;
            carry=sum/10;
            ListNode node=new ListNode(ans);
            node.next=newHead.next;
            newHead.next=node;
        }
        return newHead.next;

    }

 用链表反转实现

 /**
     * 方法2:通过链表反转来实现
     *
     * @param head1
     * @param head2
     * @return
     */
    public static ListNode addInListByReverse(ListNode head1, ListNode head2) {
        head1 = reverse(head1);
        head2 = reverse(head2);
        ListNode head = new ListNode(-1);
        ListNode cur = head;
        int carry = 0;
        while (head1 != null || head2 != null) {
            int val = carry;
            if (head1 != null) {
                val += head1.val;
                head1 = head1.next;
            }
            if (head2 != null) {
                val += head2.val;
                head2 = head2.next;
            }
            cur.next = new ListNode(val % 10);
            carry = val / 10;
            cur = cur.next;
        }
        if (carry > 0) {
            cur.next = new ListNode(carry);
        }
        return reverse(head.next);
    }

    private static ListNode reverse(ListNode head) {
        ListNode cur = head;
        ListNode pre = null;
        while (cur != null) {
            ListNode temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值