707.设计链表

707.设计链表

https://leetcode.cn/problems/design-linked-list/description/

单链表实现

单链表的创建需要一个头节点,它不存储值但指向第一个元素,便于后续的增删改查操作的实现

注意:

  • 复用 addAtIndex 函数实现添加头尾节点的功能
class ListNode{
    int val;
    ListNode next;
    public ListNode(int val){this.val = val;this.next = null;}
}

public class MyLinkedList {
    ListNode head;
    int size;
    public MyLinkedList(){
        size = 0;
        head = new ListNode(0);
    }

    public int get(int index) {
        if(index < 0 || index >= size) return -1;
        ListNode curNode = head;
        for(int count = 0; count <= index; ++count){
            curNode = curNode.next;
        }
        return curNode.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 < 0 || index > size) return;
        ListNode curNode = head;
        // 注意这里 count 没有 <= index,所以取的是index前一个节点
        for(int count = 0; count < index; ++ count){
            curNode = curNode.next;
        }
        ListNode addNode = new ListNode(val);
        ++size;
        addNode.next = curNode.next;
        curNode.next = addNode;

    }

    public void deleteAtIndex(int index) {
        if(index < 0 || index >= size) return;
        ListNode curNode = head;
        for(int count = 0; count < index; ++ count){
            curNode = curNode.next;
        }
        curNode.next = curNode.next.next;
        --size;
    }
}

双链表实现

双链表的实现,需要头,尾节点
注意:

  • 双链表则可以将头或尾节点作为起始点进行查找
  • 将链表分为两半,判断当前需要查找的节点距离哪一端更近,可以遍历更少的节点
class ListNode{
    int val;
    ListNode next;
    ListNode prev;
    public ListNode(int val){this.val = val;this.next = null;this.prev = null;}
}

class MyLinkedList {
    private ListNode head;
    private ListNode tail;
    private int size;

    public MyLinkedList() {
        head = new ListNode(0);
        tail = new ListNode(0);
        head.next = tail;
        tail.prev = head;
        size = 0;
    }
    
    public int get(int index) {
        if(index < 0 || index >= size) return -1;
        ListNode curNode;
        if(index + 1 < size - index){ // 在前半部分
            curNode = head;
            for(int i = 0; i <= index; ++i){
                curNode = curNode.next;
            }
        }else{ // 从后半部分遍历
            curNode = tail;
            for(int i = 0; i < size - index; ++i){
                curNode = curNode.prev;
            }
        }
        return curNode.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 < 0 || index > size) return;
        ListNode curNode, prevNode;
        if(index + 1 < size - index){
            curNode = head;
            for(int count = 0; count <= index; ++ count){
                curNode = curNode.next;
            }
            prevNode = curNode.prev;
        }else{
            curNode = tail;
            for(int i = 0; i < size - index; ++i){
                curNode = curNode.prev;
            }
            prevNode = curNode.prev;
        }
        ListNode addNode = new ListNode(val);
        addNode.prev = prevNode;
        addNode.next = curNode;
        prevNode.next = addNode;
        curNode.prev = addNode;
        ++size;
    }
    
    public void deleteAtIndex(int index) {
        if(index < 0 || index >= size) return;
        ListNode curNode;
        if(index + 1 < size - index){
            curNode = head;
            for(int i = 0; i <= index; ++i){
                curNode = curNode.next;
            }
        }else{
            curNode = tail;
            for(int i = 0; i < size - index; ++i){
                curNode = curNode.prev;
            }
        }
        --size;
        curNode.prev.next = curNode.next;
        curNode.next.prev = curNode.prev;
    }
}

我的实现

没有注意双链表的特性,依然用单方向的遍历实现

class ListNode{
    int val;
    ListNode next;
    ListNode prev;
    public ListNode(int val){this.val = val;this.next = null;this.prev = null;}
}

class MyLinkedList {
    private ListNode head;
    private ListNode tail;
    private int size;

    public MyLinkedList() {
        head = new ListNode(0);
        tail = new ListNode(0);
        head.next = tail;
        tail.prev = head;
        size = 0;
    }

    public int get(int index) {
        if(index < 0 || index >= size) return -1;
        ListNode curNode = head;
        for(int count = 0; count <= index; ++ count){
            curNode = curNode.next;
        }
        return curNode.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 < 0 || index > size) return;
        ListNode curNode = head;
        for(int count = 0; count <= index; ++ count){
            curNode = curNode.next;
        }
        ListNode prevNode = curNode.prev;
        ListNode addNode = new ListNode(val);
        addNode.prev = prevNode;
        addNode.next = curNode;
        prevNode.next = addNode;
        curNode.prev = addNode;
        ++size;
    }

    public void deleteAtIndex(int index) {
        if(index < 0 || index >= size) return;
        ListNode curNode = head;
        for(int count = 0; count <= index; ++ count){
            curNode = curNode.next;
        }
        --size;
        curNode.prev.next = curNode.next;
        curNode.next.prev = curNode.prev;
    }
}
  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值