目录
反转链表是面试中经常会问到的题目,可以作为模板理解后记忆。
主要有两道,一个是将一个链表全部反转,一个是将链表的m到n个节点反转。
这些模板可以应用在很多题目中比如
234. 回文链表https://leetcode-cn.com/problems/palindrome-linked-list/
链表全部反转
public class Solution {
public ListNode ReverseList(ListNode head) {
if(head==null) return head;
ListNode cur = head;// cur指向当前节点
ListNode pre = null;// pre保存上一个节点 遍历时将cur指向pre即可
while(cur != null){
ListNode nextNode = cur.next;
cur.next = pre;
pre = cur;
cur = nextNode;
}
return pre;
}
}
链表从m到n反转
public class ListNodeTest {
public static void main(String[] args) {
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
head.next.next.next = new ListNode(4);
printNode(head);
ListNode node = ReverseListmn(head, 2, 3);
printNode(node);
}
public static ListNode ReverseListmn(ListNode head, int m, int n) {
if(head==null || m>=n) return head;
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode cur = dummy;// cur指向哑结点
int k = n - m + 1;//有k个节点需要进行反转操作
while(m-- > 1){
cur = cur.next;
}
ListNode firstPart = cur;//第m各节点的前一个节点
cur = cur.next;//第m个节点
ListNode tail = cur;//第m个节点
ListNode pre = null;// pre保存上一个节点 遍历时将cur指向pre即可
ListNode nextNode = null;
while(k-- > 0 && cur != null){
nextNode = cur.next;
cur.next = pre;
pre = cur;
cur = nextNode;
}
firstPart.next = pre;
tail.next = nextNode;
return dummy.next;
}
public static void printNode(ListNode node){
while(node != null){
System.out.print(node.val+"->");
node = node.next;
}
System.out.println("null");
}
}
链表中点
快慢指针
public ListNode middleNode(ListNode head) {
if(head==null) return null;
ListNode slow = head;
ListNode fast = head;
// fast 每次走两步,slow 每次走一步
// 跳出条件 fast.next == null 说明链表节点数是奇数,此时slow节点位于中间节点
// fast.next.next == null 说明链表节点数是偶数,此时slow位于中间两个节点的左边那一个
// 可以用 1 -> 2 -> 3 1 -> 2 -> 3 -> 4 来帮助理解
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
回文链表
class Solution {
public boolean isPalindrome(ListNode head) {
if (head == null) {
return true;
}
// 找到前半部分链表的尾节点并反转后半部分链表
ListNode firstHalfEnd = endOfFirstHalf(head);
ListNode secondHalfStart = reverseList(firstHalfEnd.next);
// 判断是否回文
ListNode p1 = head;
ListNode p2 = secondHalfStart;
boolean result = true;
while (result && p2 != null) {
if (p1.val != p2.val) {
result = false;
}
p1 = p1.next;
p2 = p2.next;
}
// 还原链表并返回结果
firstHalfEnd.next = reverseList(secondHalfStart);
return result;
}
private ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
private ListNode endOfFirstHalf(ListNode head) {
ListNode fast = head;// 利用快慢指针找到链表的中间节点
ListNode slow = head;
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/92880.html