LeetCode143

以下示例  

方法一


看到题目最先想到是多次反转链表,链表不支持下标访问,无法访问到任意位置的元素,我们可以用线性表的方法来存储

在idea测试, ListNode类

public class ListNode {
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) { this.val = val; }
    ListNode(int val, ListNode next) { this.val = val; this.next = next; }

    // 添加新的结点
    public void add(int newval) {
        ListNode newNode = new ListNode(newval);
        if(this.next == null)
            this.next = newNode;
        else
            this.next.add(newval);
    }
    // 打印链表
    public void print() {
        System.out.print(this.val);
        if(this.next != null)
        {
            System.out.print("-->");
            this.next.print();
        }
    }

}


Test类
    
 public class Test {
    public static void main(String[] args) {
        ListNode l1 =new ListNode(1);
        l1.add(2);
        l1.add(3);
        l1.add(4);
        l1.add(5);
        l1.print();
        Solution s =new Solution();
        s.reorderList(l1);
        System.out.println();
        l1.print();
    }
}
   输出:
       1-->2-->3-->4-->5
       1-->5-->2-->4-->3

 

package Leetcode143;

import java.util.ArrayList;
import java.util.List;

public class Solution {
    public void reorderList(ListNode head) {
        if(head==null){   //判断是否为空
            return;
        }
        List<ListNode>list =new ArrayList<ListNode>(); //创建线性表,可以通过下标访问
        ListNode node =head;
        while (node!=null){
            list.add(node);    //向list里存储node节点 
            node=node.next;    //同时完成node节点的后移
        }
        int i=0,j= list.size()-1;   //双向取值,此时可以通过下标进行调整
        while(i<j){
            list.get(i).next=list.get(j);   //举例 取了value(1)后,将下标j==4 的节点(value=5)取到,赋值到
                                            //  list.get(0).next 里面
            i++;
            if(i==j){
                break;
            }
            list.get(j).next=list.get(i);   //同理,将原节点2(value=2)跟到节点5(value ==5)后面
            j--;
        }
        list.get(i).next = null;  //此时i 已经到尾部 
    }
}

 

方法二

采用递归的方法 (递归的思路不止一种)

这里的递归采用两头缩进的方式,每次按顺序取头结点,尾结点,然后length-2 再取里层的头结点和尾结点

 

package Leetcode143;

import java.util.ArrayList;
import java.util.List;

public class Solution {
  public void reorderList(ListNode head) {
    if (head == null || head.next == null || head.next.next == null) {
        return;
    }
    int len = 0;
    ListNode h = head;
    while (h != null) {
        len++;
        h = h.next;
    }
    reorderListRecursion(head, len);
  }
  private ListNode reorderListRecursion(ListNode head, int len) {
    if (len == 1) {          //这两种是为了考虑节点个数奇偶的情况,这种递归出口,是为了返回新的尾结点,头结点只需head.next
        ListNode outTail = head.next;    //就能获取
        head.next = null;
        return outTail;
    }
    if (len == 2) {
        ListNode outTail = head.next.next; 
        head.next.next = null;
        return outTail;
    }
    ListNode tail = reorderListRecursion(head.next, len - 2); //得到里层链表尾结点
    ListNode subHead = head.next;// 新的头结点
    head.next = tail;   
    ListNode outTail = tail.next;  //新的尾结点
    tail.next = subHead;
    return outTail;
  }
    
   //在不创建线性表的情况下,通过递归改变了关系
}

总结

方法一,较为直接,方法二的递归需要一定的思考,在链表中头结点,和尾结点的更新包含next指向问题,需要想清楚,不然会有一些小错误,这题还有快慢指针的解法,用快慢指针找到链表中点,反转链表,再将链表合并,在之后可能相关的题型里,会对此加以补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值