从尾到头打印链表
/*
* 题目:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
*
* 思路一:从尾到头,使用栈
* 思路二:直接将链表从数组尾插入,只要知道链表长度
*
* */
public int[] reversePrint1(ListNode head) {
Stack<Integer> stack = new Stack<>();
while (head != null) {
stack.add(head.val);
head = head.next;
}
int[] res = new int[stack.size()];
for (int i = 0; !stack.isEmpty(); i++) {
res[i] = stack.pop();
}
return res;
}
public int[] reversePrint2(ListNode head) {
ListNode currNode = head;
int length = 0;
while (currNode != null) {
length++;
currNode = currNode.next;
}
int[] res = new int[length];
for (int i = length - 1; i >= 0; i--) {
res[i] = head.val;
head = head.next;
}
return res;
}
反转链表
/*
* 题目:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
*
* 思路1:使用栈,直接存入每个节点
* 思路2:保存前一个节点,直接让当前节点的next指向前一个节点
*
* */
public ListNode reverseList1(ListNode head) {
if (head == null) {
return null;
}
Stack<ListNode> stack = new Stack<>();
while (head != null) {
stack.add(head);
head = head.next;
}
ListNode res = stack.pop();
ListNode currNode = res;
while (!stack.isEmpty()) {
currNode.next = stack.pop();
currNode = currNode.next;
}
currNode.next = null;
return res;
}
public ListNode reverseList2(ListNode head) {
if (head == null) {
return null;
}
ListNode preNode = head;
head = head.next;
preNode.next = null;
while (head != null) {
ListNode node = head.next;
head.next = preNode;
preNode = head;
head = node;
}
return preNode;
}
复杂链表的复制
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
/*
* 题目:
* 请实现 copyRandomList 函数,复制一个复杂链表。
* 在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
*
* 思路1:
* random 指针 可能指向任意位置的节点,所以必须所有节点都创建以后才能 copy 这一项
* 难点在于怎么识别原链表中 random 指向的 node 的位置
* 使用 Map<Node, Integer> 来记录 node 在链表中的位置
* 知道了 node 对应的位置以后 , 再遍历一遍链表 , 和 copy 后的链表关联起来 list.get(i).random = list.get(map.get(head.random));
*
* 思路2:
* random 指针 可能指向任意位置的节点,指向的节点可能还没创建,所以 copy 节点的顺序是 当前节点,下一个节点,随机节点
* 利用 原node Hash值不同区分是否已经copy
*
* */
public Node copyRandomList1(Node head) {
if (head == null) {
return null;
}
List<Node> list = new LinkedList<>();
Node currNode = head;
Map<Node, Integer> map = new HashMap<>();
int length = 0;
while (currNode != null) {
Node node = new Node(currNode.val);
list.add(node);
map.put(currNode, length++);
currNode = currNode.next;
}
for (int i = 0; i < length - 1; i++) {
list.get(i).next = list.get(i + 1);
if (head.random == null) {
list.get(i).random = null;
} else {
list.get(i).random = list.get(map.get(head.random));
}
head = head.next;
}
list.get(length - 1).next = null;
if (head.random == null) {
list.get(length - 1).random = null;
} else {
list.get(length - 1).random = list.get(map.get(head.random));
}
return list.get(0);
}
public Node copyRandomList2(Node head) {
if(head == null){
return null;
}
Map<Node, Node> map = new HashMap<>();
Node currNode = head;
map.put(null, null);
map.put(currNode, new Node(currNode.val));
while (currNode != null) {
if (!map.containsKey(currNode.next)) {
Node node = new Node(currNode.next.val);
map.put(currNode.next, node);
}
map.get(currNode).next = map.get(currNode.next);
if (!map.containsKey(currNode.random)) {
Node node = new Node(currNode.random.val);
map.put(currNode.random, node);
}
map.get(currNode).random = map.get(currNode.random);
currNode = currNode.next;
}
return map.get(head);
}