From b3c79d848410230687321964ee39f238fb9f030c Mon Sep 17 00:00:00 2001 From: donghuanjie Date: Thu, 31 Oct 2024 19:38:10 -0700 Subject: [PATCH 1/2] modified 707 code, move the ListNode class inside, reformat the code --- problems/0707.设计链表.md | 128 +++++++++++++++++----------------- 1 file changed, 63 insertions(+), 65 deletions(-) diff --git a/problems/0707.设计链表.md b/problems/0707.设计链表.md index 0cb2f2f2..ed1726d9 100644 --- a/problems/0707.设计链表.md +++ b/problems/0707.设计链表.md @@ -422,38 +422,38 @@ void myLinkedListFree(MyLinkedList* obj) { ```Java //单链表 -class ListNode { - int val; - ListNode next; - ListNode(){} - ListNode(int val) { - this.val=val; - } -} class MyLinkedList { + + class ListNode { + int val; + ListNode next; + ListNode(int val) { + this.val=val; + } + } //size存储链表元素的个数 - int size; - //虚拟头结点 - ListNode head; + private int size; + //注意这里记录的是虚拟头结点 + private ListNode head; //初始化链表 public MyLinkedList() { - size = 0; - head = new ListNode(0); + this.size = 0; + this.head = new ListNode(0); } - //获取第index个节点的数值,注意index是从0开始的,第0个节点就是头结点 + //获取第index个节点的数值,注意index是从0开始的,第0个节点就是虚拟头结点 public int get(int index) { //如果index非法,返回-1 if (index < 0 || index >= size) { return -1; } - ListNode currentNode = head; - //包含一个虚拟头节点,所以查找第 index+1 个节点 + ListNode cur = head; + //第0个节点是虚拟头节点,所以查找第 index+1 个节点 for (int i = 0; i <= index; i++) { - currentNode = currentNode.next; + cur = cur.next; } - return currentNode.val; + return cur.val; } public void addAtHead(int val) { @@ -473,7 +473,6 @@ class MyLinkedList { while (cur.next != null) { cur = cur.next; } - cur.next = newNode; size++; @@ -485,55 +484,53 @@ class MyLinkedList { // 如果 index 等于链表的长度,则说明是新插入的节点为链表的尾结点 // 如果 index 大于链表的长度,则返回空 public void addAtIndex(int index, int val) { - if (index > size) { + if (index < 0 || index > size) { return; } - if (index < 0) { - index = 0; - } - size++; + //找到要插入节点的前驱 - ListNode pred = head; + ListNode pre = head; for (int i = 0; i < index; i++) { - pred = pred.next; + pre = pre.next; } - ListNode toAdd = new ListNode(val); - toAdd.next = pred.next; - pred.next = toAdd; + ListNode newNode = new ListNode(val); + newNode.next = pre.next; + pre.next = newNode; + size++; } - //删除第index个节点 public void deleteAtIndex(int index) { if (index < 0 || index >= size) { return; } - size--; - //因为有虚拟头节点,所以不用对Index=0的情况进行特殊处理 - ListNode pred = head; + + //因为有虚拟头节点,所以不用对index=0的情况进行特殊处理 + ListNode pre = head; for (int i = 0; i < index ; i++) { - pred = pred.next; + pre = pre.next; } - pred.next = pred.next.next; + pre.next = pre.next.next; + size--; } } +``` +```Java //双链表 -class ListNode{ - int val; - ListNode next,prev; - ListNode() {}; - ListNode(int val){ - this.val = val; - } -} - - class MyLinkedList { + class ListNode{ + int val; + ListNode next, prev; + ListNode(int val){ + this.val = val; + } + } + //记录链表中元素的数量 - int size; + private int size; //记录链表的虚拟头结点和尾结点 - ListNode head,tail; + private ListNode head, tail; public MyLinkedList() { //初始化操作 @@ -541,25 +538,25 @@ class MyLinkedList { this.head = new ListNode(0); this.tail = new ListNode(0); //这一步非常关键,否则在加入头结点的操作中会出现null.next的错误!!! - head.next=tail; - tail.prev=head; + this.head.next = tail; + this.tail.prev = head; } public int get(int index) { //判断index是否有效 - if(index>=size){ + if(index < 0 || index >= size){ return -1; } - ListNode cur = this.head; + ListNode cur = head; //判断是哪一边遍历时间更短 if(index >= size / 2){ //tail开始 cur = tail; - for(int i=0; i< size-index; i++){ + for(int i = 0; i < size - index; i++){ cur = cur.prev; } }else{ - for(int i=0; i<= index; i++){ + for(int i = 0; i <= index; i++){ cur = cur.next; } } @@ -568,24 +565,23 @@ class MyLinkedList { public void addAtHead(int val) { //等价于在第0个元素前添加 - addAtIndex(0,val); + addAtIndex(0, val); } public void addAtTail(int val) { //等价于在最后一个元素(null)前添加 - addAtIndex(size,val); + addAtIndex(size, val); } public void addAtIndex(int index, int val) { - //index大于链表长度 - if(index>size){ + //判断index是否有效 + if(index < 0 || index > size){ return; } - size++; //找到前驱 - ListNode pre = this.head; - for(int i=0; i=size){ + //判断index是否有效 + if(index < 0 || index >= size){ return; } + //删除操作 - size--; - ListNode pre = this.head; - for(int i=0; i Date: Fri, 1 Nov 2024 01:12:34 -0700 Subject: [PATCH 2/2] add java recursion version of 203 --- problems/0203.移除链表元素.md | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/problems/0203.移除链表元素.md b/problems/0203.移除链表元素.md index f6b5ef6d..d51895aa 100644 --- a/problems/0203.移除链表元素.md +++ b/problems/0203.移除链表元素.md @@ -337,6 +337,37 @@ public ListNode removeElements(ListNode head, int val) { ``` +递归 + +```java +/** + * 时间复杂度 O(n) + * 空间复杂度 O(n) + * @param head + * @param val + * @return + */ +class Solution { + public ListNode removeElements(ListNode head, int val) { + if (head == null) { + return head; + } + + // 假设 removeElements() 返回后面完整的已经去掉val节点的子链表 + // 在当前递归层用当前节点接住后面的子链表 + // 随后判断当前层的node是否需要被删除,如果是,就返回 + // 也可以先判断是否需要删除当前node,但是这样条件语句会比较不好想 + head.next = removeElements(head.next, val); + if (head.val == val) { + return head.next; + } + return head; + + // 实际上就是还原一个从尾部开始重新构建链表的过程 + } +} +``` + ### Python: ```python