链表的中间节点
给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
输入:[1,2,3,4,5,6]
输出:此列表中的结点 4
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。
示例节点
/*** Definition for singly-linked list.* 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 ListNode middleNode(ListNode head) {ListNode [] A=new ListNode[100];int a=0;while (head!=null){A[a++]=head;head=head.next;}return A[a/2];}
优化1
当我们利用数组做完这道题的时候,我们再仔细地去想一想我们可以省略数组,我们进行两边遍历,第一次统计元素个数N,第二次遍历到N/2是时我们输出即可。
public ListNode middleNode(ListNode head) {int n = 0;ListNode list = head;while (list != null) {n++;list = list.next;}int k = 0;list = head;while (k < n / 2) {k++;list = list.next;}return list;}
优化2
但这一次优化我们进行了两遍遍历,我们找链表的点是一个比较特殊的一个点,在二分之一处,使用双指针中的快慢指针,一前一后,当快指针到达链表尾部时,满指针一定在链表中间位置
public ListNode middleNode(ListNode head) {ListNode slow = head, fast = head;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;}return slow;}
删除链表倒数第n个节点
示例节点
/*** Definition for singly-linked list.* 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 ListNode removeNthFromEnd(ListNode head, int n) {ListNode d=new ListNode(0,head);int lenght=get(head);ListNode c=d;for (int i=1;i<lenght-n+1;i++){c=c.next;}c.next=c.next.next;return d.next;}//获取链表长度函数public int get(ListNode head){int lenght=0;while (head!=null){lenght++;head=head.next;}return lenght;}
优化
相较于前一道题,前一道是找到中间位置,本题是指定位置,我们还是可以利用双指针,只不过之前属于定比,此题属于定差,我们只需要保证指针的距离为n,当前指针到达链表尾部是,后指针就处于n的位置
public ListNode removeNthFromEnd(ListNode head, int n) {ListNode dummy = new ListNode(0, head);ListNode first = head;ListNode second = dummy;for (int i = 0; i < n; ++i) {first = first.next;}while (first != null) {first = first.next;second = second.next;}second.next = second.next.next;ListNode ans = dummy.next;return ans;}
