简单题

剑指 Offer 06. 从尾到头打印链表

注意一个所有权的问题,另外这一题不需要先翻转链表

  1. struct Solution;
  2. impl Solution {
  3. /// 反转链表,顺序读取,再反向
  4. pub fn reverse_print(head: Option<Box<ListNode>>) -> Vec<i32> {
  5. let mut res: Vec<i32> = Vec::new();
  6. // 我们对head拥有所有权,拿进来之后将其修改为了mut的数据,
  7. // 这样可行的原因是下来的直接拥有所有权,不论如何离开这个scope之后,head都没有了
  8. // 因此可以直接进行修改
  9. let mut current = head;
  10. while let Some(mut node) = current.take() {
  11. let next = node.next.take();
  12. res.push(node.val);
  13. current = next;
  14. }
  15. res.reverse();
  16. res
  17. }
  18. }

中等

剑指 Offer 35. 复杂链表的复制

这一题乍一看感觉很简单,就是单纯的复制就行了,但是当我发现压根不能用Rust写的时候,发现问题没那么简单。如果只是简单地复制,无非就是一个虚拟头结点:

  1. public Node copyRandomList(Node head) {
  2. Node cur = head;
  3. Node dum = new Node(0), pre = dum;
  4. while(cur != null) {
  5. Node node = new Node(cur.val); // 复制节点 cur
  6. pre.next = node; // 新链表的 前驱节点 -> 当前节点
  7. // pre.random = "???"; // 新链表的 「 前驱节点 -> 当前节点 」 无法确定
  8. cur = cur.next; // 遍历下一节点
  9. pre = node; // 保存当前新节点
  10. }
  11. return dum.next;
  12. }

问题就在于,Random这个节点究竟指向谁?
因此第一个方法就是保存Random的值,两次遍历解决

法一:存map,两次遍历

map存储每一个节点的值,然后再一次遍历的时候顺序的新建即可:

  1. // 剑指 Offer 35. 复杂链表的复制
  2. public Node copyRandomList(Node head) {
  3. Node cur = head;
  4. Map<Node, Node> map = new HashMap<>();
  5. // 把自己的节点存入,
  6. while (cur != null) {
  7. map.put(cur, new Node(cur.val));
  8. cur = cur.next;
  9. }
  10. cur = head;
  11. // 这个思路没想到,之前一直固化的想要使用一个dum节点来处理
  12. // 但是发现,很难弄,而map中的值恰恰就是我们需要的新节点
  13. while (cur != null) {
  14. map.get(cur).next = map.get(cur.next); // now its new head
  15. map.get(cur).random = map.get(cur.random); // thus, can be directly used
  16. cur = cur.next;
  17. }
  18. return map.get(head);
  19. }

复杂做法:

  1. public Node copyRandomList(Node head) {
  2. Node cur = head;
  3. Map<Node, Node> map = new HashMap<>();
  4. // 把自己的节点存入,
  5. while (cur != null) {
  6. map.put(cur, new Node(cur.val));
  7. cur = cur.next;
  8. }
  9. cur = head;
  10. Node res = map.get(cur);
  11. Node dum = new Node(0);
  12. dum.next = res;
  13. while (cur != null) {
  14. res.next = map.get(cur.next);
  15. res.random = map.get(cur.random);
  16. res = res.next;
  17. cur = cur.next;
  18. }
  19. return dum;
  20. }