其他分享
首页 > 其他分享> > 一刷07-链表-707设计链表(m)

一刷07-链表-707设计链表(m)

作者:互联网

题目:
设计链表的实现。您可以选择使用单链表或双链表。
单链表中的节点应该具有两个属性:val 和 next。
val 是当前节点的值,next 是指向下一个节点的指针/引用。

如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。

假设链表中的所有节点都是 0-index 的。

在链表类中实现这些功能:

1、get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。

2、addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。
插入后,新节点将成为链表的第一个节点。

3、addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。

4、addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val  的节点。
如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。

5、deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。
----------------------------
示例:
MyLinkedList linkedList = new MyLinkedList();
linkedList.addAtHead(1);
linkedList.addAtTail(3);
linkedList.addAtIndex(1,2);   //链表变为1-> 2-> 3
linkedList.get(1);            //返回2
linkedList.deleteAtIndex(1);  //现在链表是1-> 3
linkedList.get(1);            //返回3
--------------------------
思路:
这道题目设计链表的五个接口:

1、获取链表第index个节点的数值

2、在链表的最前面插入一个节点

3、在链表的最后面插入一个节点

4、在链表第index个节点前面插入一个节点

5、删除链表的第index个节点

链表操作的两种方式:

    1)直接使用原来的链表来进行操作。

    2)设置一个虚拟头结点在进行操作。
--------------------------
代码框架:
class MyLinkedList{
    //定义链表类及相关属性

    //初始化
    public MyLinkedList(){}
    //get方法
    public int get(int index){}
    //添加头结点方法
    public void addAtHead(int val){}
    //添加尾结点方法
    public void addAtTail(int val){}
    //插入结点方法
    public void addAtIndex(int index,int val){}
    //删除结点方法
    public void deleteAtIndex(int index){}
}
------------------------
单链表模式
class MyLinkedList{
    //定义单链表类及相关属性
    class ListNode{
        int val;
        ListNode next;    
        ListNode(){}
        ListNode(int val){this.val = val;}
    }
    //定义变量size:表示链表的元素个数
    int size ;
    //定义头结点
    ListNode head;

    //初始化
    public MyLinkedList(){
        size = 0;
        head = new ListNode(0);
    }
    //get方法
    public int get(int index){
        if(index<0 || index >= size){
            return -1;
        }
        //找到当前结点
        //创建临时结点
        ListNode currentNode= head;
        for(int i = 0;i<=index;i++){
            currentNode= currentNode.next;
        }
        return currentNode.val;
    }    
    //添加头结点方法
    public void addAtHead(int val){
        addAtIndex(0,val);
    }
    //添加尾结点方法
    public void addAtTail(int val){
        addAtIndex(size,val);
    }
    //插入结点方法
    public void addAtIndex(int index,int val){
        if(index>size){
            return;
        }
        if(index<0){
            index = 0;
        }
        size++;
        //找到要插入结点位置的前驱结点
        ListNode pre = head;
        for(int i = 0;i<index;i++){
            pre = pre.next;
        }
        //对新val值创建结点
        ListNode toAdd = new ListNode(val);
        toAdd.next = pre.next;
        pre.next = toAdd;
    }
    //删除结点方法
    public void deleteAtIndex(int index){
        if(index<0 || index>=size){
            return ;
        }
        size--;
        //找到要删除结点的前驱结点
        ListNode pre = head;
        for(int i = 0;i<index;i++){
            pre = pre.next;
        } 
        pre.next = pre.next.next;
   }
}
双链表模式
class MyLinkedList{
    //定义双链表类及基本属性
    class ListNode{
        int val;
        ListNode next,prev;
        ListNode(){}
        ListNode(int val){this.val = val;}
    }
    //定义变量size:表示链表的元素个数
    int size;
    //定义头尾结点
    ListNode head,tail;
    //初始化
    public MyLinkedList(){
        size = 0;
        head = new ListNode(0);
        tail = new ListNode(0);
        head.next = tail;
        tail.prev = head;
    }
    //get方法
    public int get(int index){
        if(index<0 || index>=size){
            return -1;
        }
        //开始查找
        ListNode cur = head;
        if(index < (size-1)/2){
            for(int i=0;i<=index;i++){
                cur = cur.next;
            }
        }else{
            cur = tail;
            for(int i = 0;i<=size-index-1;i++){
                cur = cur.prev;
            }
        }
        return cur.val;
    }
    //插入头结点
    public void addAtHead(int val){
        ListNode cur = head;
        //创建新结点
        ListNode newNode = new ListNode(val);
        newNode.next = cur.next;
        cur.next.prev = newNode;
        cur.next = newNode;
        newNode.prev = cur;
        size++;
    }
    //插入尾结点
    public void addAtTail(int val){
        ListNode cur = tail;
        //创建新结点
        ListNode newNode = new ListNode(val);
        newNode.next = tail;
        newNode.prev = cur.prev;
        cur.prev.next = newNode;
        cur.prev = newNode;
        size++;
        
    }
    //插入结点
    public void addAtIndex(int index,int val){
        if(index>size){
            return;
        }
        if(index < 0){
            index = 0;
        }
        //找到插入结点的前驱结点
        ListNode cur = head;
        for(int i = 0;i<index;i++){
            cur = cur.next;
        }
        //创建新结点
        ListNode newNode = new ListNode(val);
        newNode.next = cur.next;
        newNode.prev = cur;
        cur.next.prev = newNode;
        cur.next = newNode;
        size++;
    }
    //删除结点
    public void deleteAtIndex(int index){
         if(index<0 || index>=size){
            return;
        }
        //找到删除结点的前驱结点
        ListNode cur = head;
        for(int i=0;i<index;i++){
            cur = cur.next;
        }
        //删除操作
        cur.next.next.prev = cur;//先建立prev连接
        cur.next = cur.next.next;//再建立next连接  两语句顺序反了则错误
        
        size--;
    }
}

力扣链接icon-default.png?t=LBL2https://leetcode-cn.com/problems/design-linked-list/submissions/

标签:index,ListNode,val,int,707,链表,一刷,节点
来源: https://blog.csdn.net/m0_45170946/article/details/122253742