力扣剑指offer 第2天 链表(简单) 剑指 Offer 06. 从尾到头打印链表 剑指 Offer 24. 反转链表 剑指 Offer 35. 复杂链表的复制

力扣剑指offer 第2天 链表(简单) 剑指 Offer 06. 从尾到头打印链表 剑指 Offer 24. 反转链表 剑指 Offer 35. 复杂链表的复制

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

思路

用链表存储每一个节点,然后逆序放入数组中

注意

这一题会传入 [] 空数组数据,因此需要判断head是否为null,如果为null则返回空数组[]

代码

/**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public int[] reversePrint(ListNode head) {
            if(head==null)return new int[]{};
            LinkedList<ListNode>list=new LinkedList<>();
            ListNode p = head;
            while (p.next!=null){
                ListNode t = p;
                list.push(t);
                p = p.next;
            }
            list.push(p);
            int[] ans = new int[list.size()];
            for(int i=list.size()-1;i>=0;i--){
                ans[i]=list.get(i).val;
            }
            return ans;
        }
    }

剑指 Offer 24. 反转链表

题意

将整个链表逆转,并返回逆转后的链表头结点

思路

  1. 特判head是否为空,为空直接返回head
  2. 使用三个节点指针分别记录 last=null cur=head next=head.next
  3. 如果next节点存在则更新last,cur,next(先将cur.next=last逆转指针)
  4. 当next=null时已经跳出while可此时的cur的next还未更新,所以更新它cur.next=last
  5. 返回cur(当前节点便是新的头结点)

代码

/**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode reverseList(ListNode head) {
            if(head==null)return null;
            ListNode last=null,next=head.next,cur=head;
            while (next!=null){
                cur.next = last;
                last = cur;
                cur = next;
                next = next.next;
            }
            cur.next = last;
            return cur;
        }
    }

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

题意

完全的复刻复杂链表,不可以引用原本的节点!必须自己new节点!难点在于随机指针。

思路

  1. 如果head为空返回null
  2. new一个新节点headNode作为复刻链表的头节点
  3. 创建两个动态数组l1,l2分别用来存放旧链表与新链表
  4. 如何存在下一个节点则循环遍历并复刻当前节点,同时将上一个复刻节点的next指向当前复刻节点
  5. 遍历l1,用indexOf()方法找出对应的random所在的节点下标(random为null的时候跳过判断),然后将对应l2中的节点的random设置为l2下的对应下标的节点
  6. 返回headNode复刻链表的头结点

代码

    /*
// Definition for a Node.
class Node {
    int val;
    Node next;
    Node random;

    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}
*/
    class Solution {
        public Node copyRandomList(Node head) {
            if(head==null)return null;
            final Node headNode = new Node(head.val);
            ArrayList<Node> l1 = new ArrayList<>(),l2=new ArrayList<>();
            l1.add(head);l2.add(headNode);
            while (head.next!=null){
                head = head.next;
                final Node node = new Node(head.val);
                l2.get(l2.size()-1).next = node;//将上一个新节点的next指向当前生成的新节点
                l1.add(head);l2.add(node);
            }
            //遍历l1找它们的random在的下标(null则跳过)
            int size = l1.size();
            for (int i=0;i<size;i++) {
                if(l1.get(i).random!=null){
                    l2.get(i).random = l2.get(l1.indexOf(l1.get(i).random));
                }
            }
            return headNode;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值