一、链表问题
1)使用容器(哈希表,数组等) 2)快慢指针
1、快慢指针
技巧:
慢指针:head、head.next 快指针:head.next、head.next.next 快慢指针的组合:四种情况,如下四类题目
public static class Node { public int value; public Node next; public Node(int v) { value = v; } }
- 输入链表头节点,奇数长度返回中点,偶数长度返回上中点
// head.next + head.next.next // head 头 public static Node midOrUpMidNode(Node head) { // 空链表 or 1个结点的链表 or 2个结点的链表,返回头 if (head == null || head.next == null || head.next.next == null) { return head; } // 链表有3个点或以上 Node slow = head.next; Node fast = head.next.next; // 快慢指针,慢指针一次走一步,快指针一次走两步 while (fast.next != null && fast.next.next != null) { slow = slow.next; fast = fast.next.next; } return slow; }
- 输入链表头节点,奇数长度返回中点,偶数长度返回下中点
// head.next + head.next public static Node midOrDownMidNode(Node head) { if (head == null || head.next == null) { return head; } Node slow = head.next; Node fast = head.next; while (fast.next != null && fast.next.next != null) { slow = slow.next; fast = fast.next.next; } return slow; }
- 输入链表头节点,奇数长度返回中点前一个,偶数长度返回上中点前一个
// head + head.next.next public static Node midOrUpMidPreNode(Node head) { if (head == null || head.next == null || head.next.next == null) { return null; } Node slow = head; Node fast = head.next.next; while (fast.next != null && fast.next.next != null) { slow = slow.next; fast = fast.next.next; } return slow; }
- 输入链表头节点,奇数长度返回中点前一个,偶数长度返回下中点前一个
// head + head.next public static Node midOrDownMidPreNode(Node head) { if (head == null || head.next == null) { return null; } if (head.next.next == null) { return head; } Node slow = head; Node fast = head.next; while (fast.next != null && fast.next.next != null) { slow = slow.next; fast = fast.next.next; } return slow; }
2、判断单链表是否为回文
思路:
1)栈法 -> 全部入栈,出栈与链表遍历同时对比 2)改链表 : a -> b -> c -> d -> e a -> b -> c <- d <- e 快慢指针找到中点 和 R
编码:
public static class Node { public int value; public Node next; public Node(int data) { this.value = data; } } // 栈法 // need n extra space public static boolean isPalindrome1(Node head) { Stack<Node> stack = new Stack<Node>(); Node cur = head; while (cur != null) { stack.push(cur); cur = cur.next; } while (head != null) { if (head.value != stack.pop().value) { return false; } head = head.next; } return true; } // 链表反转法 1 // need n/2 extra space