[LeetCode] 707. Design Linked List

原题链接: https://leetcode.com/problems/design-linked-list/

1. 题目介绍

题目非常长,简单来说,需要我们设计并实现一个链表类。

什么是链表类呢?
我们知道,链表中最重要的就是 Node 类,Node 定义了链表的节点。但是这些 Node 类如何将它们连接起来呢?这就需要设计一个新的类:链表类,由它来负责链表的增、删、改等操作。本题就是让我们写一个链表类。

Design your implementation of the linked list. You can choose to use the singly linked list or the doubly linked list. A node in a singly linked list should have two attributes: val and next. val is the value of the current node, and next is a pointer/reference to the next node. If you want to use the doubly linked list, you will need one more attribute prev to indicate the previous node in the linked list. Assume all nodes in the linked list are 0-indexed.
设计实现一个链表类。可以使用单向链表或者双向链表设计。
如果是单向链表,链表节点需要有val 和 next 两个属性。val是节点的值,next是下一个节点。
如果是双向链表,需要 val 、next 和 prev 三个属性。prev是上一个节点。
假设,所有的节点的标号都是从0开始的。也就是头节点是第 0 个节点。

Implement these functions in your linked list class:
下面是链表类需要实现的方法:

  1. get(index) :
    Get the value of the index-th node in the linked list. If the index is invalid, return -1.
    得到第index个节点的val值,如果index不存在,返回-1
  2. addAtHead(val) :
    Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list.
    在链表头部插入一个新节点,新增的节点成为链表新的头节点
  3. addAtTail(val) :
    Append a node of value val to the last element of the linked list.
    在链表的尾部插入一个新节点
  4. addAtIndex(index, val) :
    Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted.
    在第 index 个节点前插入一个新节点。如果 index 刚好是链表的长度,那么这个插入的新节点会成为链表的尾节点。如果index 大于链表的长度,这个节点不会被插入。
  5. deleteAtIndex(index) :
    Delete the index-th node in the linked list, if the index is valid.
    如果有第 index 个节点,那么删除第 index 个节点。

Example:

MyLinkedList linkedList = new MyLinkedList();
linkedList.addAtHead(1);
linkedList.addAtTail(3);
linkedList.addAtIndex(1, 2);  // linked list becomes 1->2->3
linkedList.get(1);            // returns 2
linkedList.deleteAtIndex(1);  // now the linked list is 1->3
linkedList.get(1);            // returns 3

Note:

All values will be in the range of [1, 1000].
The number of operations will be in the range of [1, 1000].
Please do not use the built-in LinkedList library.

所有 val 值的范围是[1, 1000].
操纵的次数范围是[1, 1000].
不要使用 LinkedList 库。

2. 解题思路

本题的实现较为简单,就是对链表进行增、删操作即可。这些都是比较基本的操作。
我是采用单向链表实现的。
但是最后一个样例是一个神坑,我在这个样例上面错了很久。
在这里插入图片描述

问题的关键在于对 addAtIndex(index, val) 函数的理解。
addAtIndex(index, val) 的说明如下:
Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted.

该函数的说明指出,要在第 index 个节点前面插入一个新节点。
如果index 等于链表的长度,那么就要把节点插入到链表的结尾;
如果index 大于链表的长度,不会插入节点。

这里面暗含了一种情况:当链表长度为0, index 为 -1 时。
这种情况下,即使现在链表的长度为0,也要在第 -1 个节点(虽然这个节点不存在)前面插入一个节点。
所以。当链表为空时,如果addAtIndex(-1,0),会在链表的头部插入一个 val = 0 的节点。

而我之前错的原因是,一旦判断 index < 0 , 就直接返回 -1了。

虽然这道题过了,但是我仍然觉得自己之前返回-1的做法是正确的,因为那时候index = -1 是不符合规则的嘛。

实现代码

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

    private ListNode root;//链表头节点
    private int length;//链表长度

    /** Initialize your data structure here. */
    //初始化链表
    public MyLinkedList() {
    	this.root = null;
        this.length = 0;
    }
    
    /** Get the value of the index-th node in the linked list. 
    If the index is invalid, return -1. */
    //得到第index个节点的值
    public int get(int index) {
        if (index > length-1 || index < 0) {
            return -1;//如果index为非法,返回-1
        }
        ListNode cur = this.root;
        for (int i = 0 ; i < index ; i++ ) {
            cur = cur.next;
        }
        return cur.val;
    }
    
    /** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */
    //在头节点之前插入节点,成为新的头节点
    public void addAtHead(int val) {
        ListNode newHead = new ListNode(val);
        newHead.next = this.root;
        this.root = newHead;
        this.length ++;
    }
    
    /** Append a node of value val to the last element of the linked list. */
    //在为尾节点后插入节点
    public void addAtTail(int val) {
        ListNode newTail = new ListNode(val);
        if (this.root == null) {
            this.root = newTail;
        }else{
            ListNode cur = this.root;
            while (cur.next != null ) {
              cur = cur.next;
            }
            cur.next = newTail;
        }
        this.length ++;
    }
    
    /** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */
    public void addAtIndex(int index, int val) {
        if (index > length ) {
        	return;
        }
        else if (index <= 0) {
        	addAtHead(val);
        }
        else if (index == length) {
        	addAtTail(val);
        }
        else{
        	ListNode cur = this.root;
        	for (int i = 0; i < index-1 ; i++ ) {
        		cur = cur.next;
        	}

        	ListNode newNode = new ListNode(val);
        	newNode.next = cur.next;
        	cur.next = newNode;
        	this.length ++;
        }

    }
    
    /** Delete the index-th node in the linked list, 
    if the index is valid. */
    public void deleteAtIndex(int index) {
        if (index > length-1 || index <0) {
        	return;
        }
        else if (index == 0) {
        	this.root = this.root.next;
        }
        else{
        	ListNode cur = this.root;
        	for (int i = 0; i < index-1 ; i++ ) {
        		cur = cur.next;
        	}
        	cur.next = cur.next.next;
        }

        this.length --;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值