206.反转链表
1、迭代
/**
* 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; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null){
return head;
}
ListNode cur = head.next, pre = head, temp;
pre.next = null; //让第一个节点指向null
while (cur != null){
temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
}
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:37.6 MB, 在所有 Java 提交中击败了99.47%的用户
2、递归
链表天然具有递归的性质
递归的三个条件
-
大问题拆成两个子问题
-
子问题求解方式和大问题一样
-
存在最小子问题
1 | —> | 2 | —> | 3 | —> | null |
---|---|---|---|---|---|---|
2 | —> | 3 | —> | null | ||
3 | —> | null |
class Solution {
public ListNode reverseList(ListNode head) {
//1.递归终止条件
if (head == null || head.next == null){
return head;
}
ListNode cur = reverseList(head.next);
head.next.next = head;
head.next = null;
return cur;
}
}
人傻了,还是需要多想想。
234.回文链表
我的解法
/**
* 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; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
ArrayList<Integer> list = new ArrayList<Integer>();
int len = 0;
while (head != null){
list.add(head.val);
len++;
head = head.next;
}
int pre = 0;
while (pre <= len){
if (list.get(pre) != list.get(len - 1)){
return false;
}
pre++;
len--;
}
return true;
}
}
执行用时:8 ms, 在所有 Java 提交中击败了40.21%的用户
内存消耗:50.7 MB, 在所有 Java 提交中击败了36.77%的用户
注意动态数组的声明Integer首字母大写
ArrayList<Integer> list = new ArrayList<Integer>();
官方解法
2、递归
3、快慢指针
237.删除链表中的节点
不要被删除这个词迷惑而想方设法去删除这个节点,我们可以采用移山填海、偷梁换柱的做法,把下一个节点的值赋给这一个节点,同时让这个节点指向下下个节点。
class Solution {
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
}
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:37.4 MB, 在所有 Java 提交中击败了94.40%的用户