一、反转链表
题目:给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
这里使用的是双指针的方法
代码:
//定义链表
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 reverseList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
ListNode temp = null;
while(cur != null){
temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
首先定义一个cur指针指向起始链表的头指针head,再定义一个pre指针指向cur的前一位元素,由于这里指向cur前一位元素为空,所以这里初始化pre = null,temp是一个暂存的指针,用于保存cur移动时所要移动到的位置
在进入循环后,遍历原链表中所有的数据,直到cur指向链表尾部(即为null时),说明遍历结束,将cur的next元素暂时交给temp保存,作为最后cur要移动的位置,之后反转指针,让cur的next位指向pre所在的null作为链表尾部,然后先pre右移到cur的位置,再让cur右移到temp所保存的位置,最后返回pre,此时的pre就成为了反转之后的链表的头指针了
二、两两交换链表中的节点
题目:
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。
例子:1->2->3->4 交换后 2->1->4->3
思路:定义虚拟头指针dumy 记录接下来的三个节点的位置(暂存)
初始化链表
public class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
交换过程
public ListNode swapPairs(ListNode head) {
ListNode dumy = new ListNode(-1);
dumy.next = head;
ListNode temp;
ListNode cur = dumy;
ListNode firstTemp,secondTemp;
while(cur.next != null&&cur.next.next != null){ //判断,如果链表元素个数是偶数,则cur的下一个为空,反之为奇数个,则为cur的下一位的下一个为空,以下拿 cur->1->2 举例
temp = cur.next.next.next; //将cur的下一位的下一位的下一位暂存给temp
firstTemp = cur.next; //将cur的下一位暂存给firstTemp
secondTemp = cur.next.next; //将cur的下一位的下一位暂存给secondTemp
cur.next = secondTemp; //将cur的指针指向第二位元素 即cur->2
cur.next.next = firstTemp; //将第二号元素的指针指向第一号元素 即 2->1
firstTemp.next = temp; //将第一号元素指向第三号 即 1->3
cur = firstTemp; //此时第一轮完成操作 交换后的结果为 cur->2->1->3 更新cur 的位置到下一组的前一个指针节点,接下来更新交换3和4,所以cur应指向1的位置
}
return dumy.next; //dumy是虚拟头节点,因此应返回头节点,即为dumy.next
}
图示
整理拉直后
三、删除链表中倒数第N个节点
题目:给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
思路:
关键是如何锁定到倒数第N个节点
方法:
这里采用双指针的方法,定义快慢指针,让快指针先走N个距离,随后让快慢指针一起移动,当快指针指向链表尾部(即快指针指向null时),此时慢指针的位置刚好是倒数第N个的节点,大致思路就是如此
代码:
定义链表
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 dumy = new ListNode(-1); //定义虚拟头节点
dumy.next = head; //令虚拟头节点指向头节点head
ListNode fast = dumy; //定义快慢指针指向虚拟节点
ListNode slow = dumy;
for(int i = 0;i<=n;i++){ //先让快指针移动N个距离
fast = fast.next;
}
while(fast != null){ //如果快指针不为空,说明没有到链表尾,快慢指针在相隔N个位置距离的同时一起移动
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next; //快指针到达表尾,此时慢指针指向倒数第N个节点的前一个位置,执行删除操作,直接让慢指针指向下一个节点的下一个节点
return dumy.next; //返回头节点
}
今天的学习就到这里了