[leetcode]第 2 天 链表(简单)
06. 从尾到头打印链表
思路
说到从尾到头,很容易想到可以用到栈的方式进行处理,那么问题就转化成了如何用辅助栈完成打印链表。可以从链表的头节点开始,依次将每个节点压入栈内,然后依次弹出栈内的元素并存储到数组中。使用到LinkedList的addLast()和removeLast()。
在题目里有一个ListNode对象,ListNode是做什么用的?
public class ListNode{
int val;
ListNode next; //链表指向的下一个值的指针
ListNode(int x){val = x;} //这个方式赋值
}
class Solution {
public int[] reversePrint(ListNode head) {
LinkedList<Integer> stack = new LinkedList<Integer>();
while(head != null){
stack.addLast(head.val);
head = head.next;
}
int[] a = new int[stack.size()];
for(int i = 0; i < a.length; i++){
a[i] = stack.removeLast();
}
return a;
}
}
24. 反转链表
思路
一看到反转就想用栈,但是实际上这道题的思路不是这样的。
反转链表的思路是更改指针的方向,流程是:
- 保存下一节点
- 修改指针方向
- 保存当前节点
- 处理下一节点
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur = head, pre = null;
while(cur != null) {
ListNode tmp = cur.next;
cur.next = pre;
pre = cur;
cur = tmp;
}
return pre;
}
}
35. 复杂链表的复制
思路
看不懂的题目。。。
官方给出的方法有两种,一种是利用哈希表,一种是利用节点拆分。
如果是普通链表,就能按照遍历的顺序创建链表节点,由于随机指针的存在,拷贝时随机指针指向的节点可能还未被创建。
思路一是让每个节点的拷贝操作相互独立。就是先拷贝当前节点,再拷贝当前节点的后继节点和当前节点随机指针指向的节点,这两个节点还不存在就去拷贝,因此需要用到递归。
为了避免重复创建,可以用到HashMap存储节点创建情况。如果节点为空,则返回null。
class Solution{
Map<Node, Node> nodeMap = new HashMap<Node, Node>();
public Node copyRandomList(Node head){
// 节点为空
if(head == null){
return null;
}
// 如果节点未被创建
if(!nodeMap.containsKey(head)){
Node headNew = new Node(head.val);
// 存map
nodeMap.put(head, headNew);
// 创建next节点
headNew.next = copyRandomList(head.next);
// 创建random节点
headNew.random = copyRandomList(head.random);
}
return nodeMap.get(head);
}
}
第二种思路是迭代+节点拆分,就是说将每一个节点拆成两个相连的节点,即A->B->C->D拆成A->A'->B->B'->C->C'。
对于原节点,后继节点为拷贝节点。
对于拷贝节点,随机指针指向原节点随机指针指向的节点的后继节点。(S'.random = S.random.next)
class Solution {
public Node copyRandomList(Node head) {
if (head == null) {
return null;
}
// 复制链表节点,插入原节点后方
Node cur = head;
while(cur != null){
Node next = cur.next;// 保存下一节点
cur.next = new Node(cur.val);// new一个新节点
cur.next.next = next;
cur = next;// 向右移动
}
// 复制随机节点
cur = head;
while(cur != null){
Node curNew = cur.next;// 保存下一节点
curNew.random = cur.random == null? null : cur.random.next;
cur = cur.next.next;
}
// 拆分
Node headNew = head.next;
cur = head;
Node curNew = head.next;
while(cur != null){
cur.next = cur.next.next;
cur = cur.next;
curNew.next = cur == null? null : cur.next;
curNew = curNew.next;
}
return headNew;
}
}