反转链表(简单的)
先来个简单的反转链表,用处大大地,后面的其他链表题会用到反转链表这个步骤哦
题目描述
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
思路
递归法
- 递归的终止是:当前节点为空 或者 它的指向为空
- 反转当前节点,先反转下一个节点;
- 下一个节点指向当前节点;
- 当前节点指向空;
Java代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
//递归法
if(head == null || head.next == null) return head;
//新的头节点
ListNode newHead = reverseList(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
}
回文链表
看,用处来了吧
题目描述
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
思路
只需要判断一个链表的前半段和后半段反转后的节点值是否一一相同就行了。
怎么找出前半段,后半段呢?
快慢指针法这个方法在链表题中很有用,要记住。比如,它可以找出链表的倒数第几个节点。这里相当于是找到倒数一半的节点。
- 先找出前、后半段
- 反转后半段(上题的递归法)
- 一一对比前后半段的节点值
Java代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
//递归反转一个链表
public ListNode reverse(ListNode head){
if(head.next == null) return head;
ListNode newHead = reverse(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
public boolean isPalindrome(ListNode head) {
//特殊情况
if(head ==null || head.next == null) return true;
//快慢指针,寻找中点
ListNode fast = head;
ListNode slow = head;
while(fast.next!=null && fast.next.next != null){
slow = slow.next;
fast = fast.next.next;
}
//翻转后半段
slow = reverse(slow.next);
//对比
while(slow!=null){
if(head.val!=slow.val) return false;
head = head.next;
slow = slow.next;
}
return true;
}
}