2022-2-12剑指offer day2

题1:

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

 

示例 1:

输入:head = [1,3,2]
输出:[2,3,1]

 

限制:

0 <= 链表长度 <= 10000

 1 /**
 2  * Definition for singly-linked list.
 3  * public class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode(int x) { val = x; }
 7  * }
 8  */
 9 class Solution {
10     
11     // public int[] reversePrint(ListNode head) {
12     //     List<Integer> list=new ArrayList<>();
13     //     while (head!=null) {
14     //         list.add(head.val);
15     //         head=head.next;
16     //     }
17     //     int n=list.size();
18     //     int[] a=new int[n];
19     //     for (int i=n-1;i>=0;i--) a[i]=list.get(n-i-1);
20     //     return a;
21     // }
22 
23 
24         public int[] reversePrint(ListNode head) {
25             if (head==null) return new int[]{};
26             int[] a=reversePrint(head.next);
27             int[] res=new int[a.length+1];
28             res[res.length-1]=head.val;
29             for (int i=0;i<a.length;i++) {
30                 res[i]=a[i];
31             }
32             return res;
33     }
34 }

思路:方法1,递归,将当前节点拼在新的数组后面。方法二,遍历链表,倒序填充在数组中。

题2:

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

 

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

 

限制:

0 <= 节点个数 <= 5000

 1 /**
 2  * Definition for singly-linked list.
 3  * public class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode(int x) { val = x; }
 7  * }
 8  */
 9 class Solution {
10     public ListNode reverseList(ListNode head) {
11         // 如果head空或者下一个为空直接返回head
12         if (head==null||head.next==null) return head;
13         // 记录当前节点的下一个
14         ListNode temp=head.next;
15         // 除当前节点外 反转后的头节点
16         ListNode tail=reverseList(head.next);
17         // 将原来节点的反转
18         temp.next=head;
19         // 新的结尾加上null
20         head.next=null;
21         return tail;
22     }
23 
24 
25 }

思路: 递归。具体见注释。

题3:

请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null

 

示例 1:

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

示例 2:

输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]

示例 3:

输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]

示例 4:

输入:head = []
输出:[]
解释:给定的链表为空(空指针),因此返回 null。

 

提示:

  • -10000 <= Node.val <= 10000
  • Node.random 为空(null)或指向链表中的节点。
  • 节点数目不超过 1000 。

 

 1 /*
 2 // Definition for a Node.
 3 class Node {
 4     int val;
 5     Node next;
 6     Node random;
 7 
 8     public Node(int val) {
 9         this.val = val;
10         this.next = null;
11         this.random = null;
12     }
13 }
14 */
15 class Solution {
16     public Node copyRandomList(Node head) {
17         if (head==null) return head;
18         Node temp=head;
19         while (temp!=null) {
20             Node behind=temp.next;
21             Node cross=new Node(temp.val);
22             temp.next=cross;
23             cross.next=behind;
24             temp=behind;
25         }
26         temp=head;
27         while (temp!=null) {
28             if (temp.random!=null) temp.next.random=temp.random.next;
29             temp=temp.next.next;
30         }
31         Node dummy=head.next;
32         Node p1=head,p2=head.next;
33         while (p2.next!=null) {
34             p1.next=p1.next.next;
35             p2.next=p2.next.next;
36             p1=p1.next;
37             p2=p2.next;
38         }
39         p1.next=null;
40         return dummy;
41     }
42 }

思路:第一次遍历在原来的链表后面先添加一个相同的节点。第二次遍历,将新节点的ranbom复制到对应的新节点上。第三次遍历,将复制链表和原链表分开。

posted on 2022-02-12 12:52  阿ming  阅读(23)  评论(0)    收藏  举报

导航