设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val
和 next
。val
是当前节点的值,next
是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev
以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。
在链表类中实现这些功能:
- get(index):获取链表中第
index
个节点的值。如果索引无效,则返回-1
。 - addAtHead(val):在链表的第一个元素之前添加一个值为
val
的节点。插入后,新节点将成为链表的第一个节点。 - addAtTail(val):将值为
val
的节点追加到链表的最后一个元素。 - addAtIndex(index,val):在链表中的第
index
个节点之前添加值为val
的节点。如果index
等于链表的长度,则该节点将附加到链表的末尾。如果index
大于链表长度,则不会插入节点。 - 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, 1000]
之内。 - 操作次数将在
[1, 1000]
之内。 - 请不要使用内置的 LinkedList 库。
思路:数据结构链表的设计,对于初次接触编程的非计算机专业读者可能有一定难度,就是理解好链表的删除节点和增加节点时,需要获取目标节点的前一节点。
目前 beat 99.3%。 欢迎萌新留言,虽然我也是个非计算机专业的萌新。详见代码。
class MyLinkedList { int size; //链表大小 ListNode head; //链表头部指针 ListNode tail; //这是指向链表的尾部节点的指针 public MyLinkedList() { } //获取链表索引index处的Node节点的value,如果索引超出链表范围则返回-1 public int get(int index) { if(index>size-1) return -1; int cnt=0; ListNode temp=head; while(cnt!=index){ temp = temp.next; cnt++; } return temp.val; } //新建一个Node 让其指向当前的链表头部head,并更新当前链表的头部指针head public void addAtHead(int val) { if(head==null){ head = new ListNode(val); size++; tail = head; } else { ListNode temp = new ListNode(val); temp.next = head; head = temp; size++; } } //新建一个node,让当前尾部节点tail指向该node,即tai.next=node,并更新tail=tail.next; public void addAtTail(int val) { if(head==null){ head = new ListNode(val); size++; tail = head; } else{ ListNode temp = new ListNode(val); tail.next = temp; tail = tail.next; size++; } } //在链表插入的过程中需要获取其前面的一个节点 public ListNode getPreNode(int index){ int cnt=0; ListNode temp = head; while(temp.next!=null){ if(cnt!=index-1){ temp = temp.next; cnt++; } else break; } return temp; } //增加节点,注意index为0 和size-1的特殊情况 public void addAtIndex(int index, int val) { if(index==0) {addAtHead(val); return ;} if(index==size) {addAtTail(val);return ;} if(index<=size-1){ ListNode temp = getPreNode(index); ListNode tempnext = temp.next; ListNode newNode = new ListNode(val); temp.next = newNode; newNode.next = tempnext; size++; } } //删除链表中某节点 public void deleteAtIndex(int index) { if(index<size){ if(index==0) {head=head.next;size--;} else{ ListNode temp = getPreNode(index); if(index==size-1) { temp.next = null; tail = temp; size--; } else { ListNode tempnn = temp.next.next; temp.next = tempnn; size--; } } } } //内部类,一个链表的节点 class ListNode { int val; ListNode next; ListNode(int x){val = x;} } }