707. 设计链表[双向链表]

思路

使用双向链表,不使用哨兵,并通过一个len记录链表的长度,从而简化判断index是否合法的操作。
需要特殊处理的情况有:

  1. 长度为0情况下的元素添加
  2. 长度为1情况下元素的删除和添加

代码如下:

public class MyLinkedList {
    private Node head;
    private Node tail;
    private Integer len;

    private static class Node {
        public int val;
        public Node prev;
        public Node next;

        public Node(){
        }

        public Node(int val){
            this.val = val;
        }

        public Node(int val, Node prev, Node next) {
            this.val = val;
            this.prev = prev;
            this.next = next;
        }
    }

    public MyLinkedList() {
        len = 0;
    }

    private Node getNode(int index){
        //内部使用,保证index的值合法
        Node node = head;
        for (int i = 0; i < index; i++) {
            node = node.next;
        }
        return node;
    }

    public int get(int index) {
       if (index < 0 || index >= len){
           return -1;
       }
       return getNode(index).val;
    }

    public void addAtHead(int val) {
        Node node = new Node(val);
        if (len == 0){
            head = node;
            tail = node;
            len++;
            return;
        }
        //连接两节点
        node.next = head;
        head.prev = node;
        //更新头节点
        head = node;
        //长度+1
        len++;
    }

    public void addAtTail(int val) {
        Node node = new Node(val);
        if (len == 0){
            head = node;
            tail = node;
            len++;
            return;
        }
        //连接两节点
        node.prev = tail;
        tail.next = node;
        //更新头节点
        tail = node;
        //长度+1
        len++;
    }

    //在index节点前添加,使得添加后val的下标为index
    public void addAtIndex(int index, int val) {
        if (index <= 0){
            //都是加在头部
            addAtHead(val);
            return;
        } else if (index == len) {
            //加在尾部
            addAtTail(val);
            return;
        } else if (index > len) {
            return;
        }

        //此时链表长度至少为2
        //加在node节点前
        //三个节点的连接
        Node node = getNode(index);
        Node newNode = new Node(val, node.prev, node);
        node.prev.next = newNode;
        node.prev = newNode;
        //长度+1
        len++;
    }

    public void deleteAtIndex(int index) {
        if (index < 0 || index >= len){
            //索引无效
            return;
        }
        
        //特判长度为1的情况
        if (len == 1){
            head = tail = null;
            len--;
            return;
        }
        //长度至少为2的情况,头尾指针最多只需要修改一个
        if (index == 0){
            //删头
            head = head.next;
            //删除连接
            head.prev.next = null;
            head.prev = null;
        } else if (index == len-1){
            //删尾
            tail = tail.prev;
            //删除连接
            tail.next.prev = null;
            tail.next = null;
        } else {
            //删除中间节点
            Node node = getNode(index);
            //删除连接
            node.prev.next = node.next;
            node.next.prev = node.prev;
            node.next = null;
            node.prev = null;
        }

        //长度-1
        len--;
    }
}

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList obj = new MyLinkedList();
 * int param_1 = obj.get(index);
 * obj.addAtHead(val);
 * obj.addAtTail(val);
 * obj.addAtIndex(index,val);
 * obj.deleteAtIndex(index);
 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值