From f875a1841e2c5e051b45ce264694f047ac4d713f Mon Sep 17 00:00:00 2001 From: dingjiawen <745518019@qq.com> Date: Mon, 5 Sep 2022 15:19:07 +0800 Subject: [PATCH] =?UTF-8?q?leecode=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../leecode/listnode/MyLinkedList.java | 301 +++++++++++++++++ .../leecode/listnode/MyLinkedList1.java | 313 ++++++++++++++++++ .../leecode/listnode/RemoveElement.java | 157 +++++++++ 3 files changed, 771 insertions(+) create mode 100644 Leecode/src/main/java/com/markilue/leecode/listnode/MyLinkedList.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/listnode/MyLinkedList1.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/listnode/RemoveElement.java diff --git a/Leecode/src/main/java/com/markilue/leecode/listnode/MyLinkedList.java b/Leecode/src/main/java/com/markilue/leecode/listnode/MyLinkedList.java new file mode 100644 index 0000000..257ae3c --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/listnode/MyLinkedList.java @@ -0,0 +1,301 @@ +package com.markilue.leecode.listnode; + +import org.junit.Test; + +/** + * 设计链表: + * 设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val和next。val是当前节点的值,next是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性prev以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。 + * + * 在链表类中实现这些功能: + * + * get(index):获取链表中第index个节点的值。如果索引无效,则返回-1。 + * addAtHead(val):在链表的第一个元素之前添加一个值为val的节点。插入后,新节点将成为链表的第一个节点。 + * addAtTail(val):将值为val 的节点追加到链表的最后一个元素。 + * addAtIndex(index,val):在链表中的第index个节点之前添加值为val 的节点。如果index等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。 + * deleteAtIndex(index):如果索引index 有效,则删除链表中的第index 个节点。 + * + * Your MyLinkedList object will be instantiated and called as such: + * MyLinkedList obj = new MyLinkedList(); + * int param_1 = obj.get(index); + * obj.addAtHead(val); + * obj.addAtTail(val); + * obj.addAtIndex(index,val); + * obj.deleteAtIndex(index); + */ +public class MyLinkedList { + + public ListNode head; + + public MyLinkedList() { + + } + + public int get(int index) { + + int count = 0; + //避免head发生变化 + ListNode temp=head; + while (count!=index&&temp!=null){ + temp = temp.next; + count++; + } + //找到了对应的index + if(count==index){ + if(temp!=null){ + return temp.val; + } + } + + return -1; + + } + + public void addAtHead(int val) { + if(head==null){ + head=new ListNode(val); + return; + } + ListNode neededAddNode = new ListNode(val); + ListNode tempHead=new ListNode(0); + tempHead.next=neededAddNode; + neededAddNode.next=head; + head=tempHead.next; + + } + + public void addAtTail(int val) { + if(head==null){ + head=new ListNode(val); + return; + } + ListNode temp=head; + while (temp.next!=null){ + temp=temp.next; + } + temp.next=new ListNode(val); + + } + + public void addAtIndex(int index, int val) { + if(index>getSize()){ + return; + } + + if(index<=0){ + addAtHead(val); + } + + int count = 0; + //避免head发生变化 + ListNode temp=head; + while (count!=index-1&&temp.next!=null){ + temp = temp.next; + count++; + } + //找到了对应的index + if(count==index-1){ + ListNode need = new ListNode(val); + need.next=temp.next; + temp.next=need; + }else { + System.out.println("index超过限制"); + } + + } + + public void deleteAtIndex(int index) { + + if(head==null){ + return; + } + + if(index==0){ + head=head.next; + return; + } + + int count = 0; + //避免head发生变化 + ListNode temp=head; + while (count!=index-1&&temp.next!=null){ + temp = temp.next; + count++; + } + //找到了对应的index + if(count==index-1){ + if(temp.next!=null){ + temp.next=temp.next.next; + } + }else { + System.out.println("index超过限制"); + } + + } + + public void printList(ListNode head) { + + if(head==null){ + System.out.println("链表为空"); + return; + } + + while (head!=null){ + System.out.printf(head.val+"->"); + head=head.next; + } + + System.out.println(); + + + } + + public int getSize(){ + int size=0; + ListNode temp=head; + while (temp!=null){ + size+=1; + temp=temp.next; + } + + return size; + } + + + @Test + public void test(){ + MyLinkedList linkedList = new MyLinkedList(); + linkedList.addAtHead(1); + printList(linkedList.head); + System.out.println(); + linkedList.addAtTail(3); + printList(linkedList.head); + System.out.println(); + linkedList.addAtIndex(1,2); //链表变为1-> 2-> 3 + printList(linkedList.head); + System.out.println(); + System.out.println(linkedList.get(1)); +// printList(linkedList.head); + System.out.println(); + linkedList.deleteAtIndex(1); //现在链表是1-> 3 + printList(linkedList.head); + System.out.println(); + System.out.println(linkedList.get(1)); + + + } + @Test + public void test1(){ + MyLinkedList linkedList = new MyLinkedList(); + linkedList.addAtHead(7); + printList(linkedList.head); + + linkedList.addAtHead(2); + printList(linkedList.head); + + linkedList.addAtHead(1); + printList(linkedList.head); + + linkedList.addAtIndex(3,0); + printList(linkedList.head); + + linkedList.deleteAtIndex(2); + printList(linkedList.head); + + linkedList.addAtHead(6); + printList(linkedList.head); + + linkedList.addAtTail(4); + printList(linkedList.head); + + System.out.println(linkedList.get(4)); + + linkedList.addAtHead(4); + printList(linkedList.head); + + linkedList.addAtIndex(5,0); + printList(linkedList.head); + + linkedList.addAtHead(6); + printList(linkedList.head); + + +// System.out.println(linkedList.get(1)); +//// printList(linkedList.head); +// System.out.println(); +// linkedList.deleteAtIndex(1); //现在链表是1-> 3 +// printList(linkedList.head); +// System.out.println(); +// System.out.println(linkedList.get(1)); + + + } + @Test + public void test2(){ + MyLinkedList linkedList = new MyLinkedList(); + linkedList.addAtHead(2); + printList(linkedList.head); + + linkedList.deleteAtIndex(1); + printList(linkedList.head); + + linkedList.addAtHead(2); + printList(linkedList.head); + + linkedList.addAtHead(7); + printList(linkedList.head); + + linkedList.addAtHead(3); + printList(linkedList.head); + + linkedList.addAtHead(2); + printList(linkedList.head); + + linkedList.addAtHead(5); + printList(linkedList.head); + + linkedList.addAtTail(5); + printList(linkedList.head); + + System.out.println(linkedList.get(5)); + + linkedList.deleteAtIndex(6); + printList(linkedList.head); + + linkedList.deleteAtIndex(4); + printList(linkedList.head); + + + } + + @Test + public void test3(){ + MyLinkedList linkedList = new MyLinkedList(); + linkedList.addAtHead(1); + printList(linkedList.head); + + + linkedList.addAtTail(3); + printList(linkedList.head); + + linkedList.addAtIndex(1,2); + printList(linkedList.head); + + + System.out.println(linkedList.get(1)); + + linkedList.deleteAtIndex(1); + printList(linkedList.head); + + System.out.println(linkedList.get(1)); + + + } + + /* + 错了四五次之后通过 + 内存超过79.95%,速度超过9.96%,慢的原因:每次都要算一遍getSize + 改进:维护一个变量size,每次容量变化都让size也跟着变化一次;此外,还可以维护一个虚拟的头结点,不存放任何数据; + 具体操作参考MyLinkedList1 + */ +} + diff --git a/Leecode/src/main/java/com/markilue/leecode/listnode/MyLinkedList1.java b/Leecode/src/main/java/com/markilue/leecode/listnode/MyLinkedList1.java new file mode 100644 index 0000000..e022842 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/listnode/MyLinkedList1.java @@ -0,0 +1,313 @@ +package com.markilue.leecode.listnode; + +import org.junit.Test; + +/** + * 设计链表: + * 设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val和next。val是当前节点的值,next是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性prev以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。 + *

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

+ * get(index):获取链表中第index个节点的值。如果索引无效,则返回-1。 + * addAtHead(val):在链表的第一个元素之前添加一个值为val的节点。插入后,新节点将成为链表的第一个节点。 + * addAtTail(val):将值为val 的节点追加到链表的最后一个元素。 + * addAtIndex(index,val):在链表中的第index个节点之前添加值为val 的节点。如果index等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。 + * deleteAtIndex(index):如果索引index 有效,则删除链表中的第index 个节点。 + *

+ * Your MyLinkedList object will be instantiated and called as such: + * MyLinkedList obj = new MyLinkedList(); + * int param_1 = obj.get(index); + * obj.addAtHead(val); + * obj.addAtTail(val); + * obj.addAtIndex(index,val); + * obj.deleteAtIndex(index); + */ +public class MyLinkedList1 { + + //该head为虚拟节点,不存放任何数据 + public ListNode head; + public int size; + + public MyLinkedList1() { + head = new ListNode(0); + size = 0; + } + + public int get(int index) { + + if (size < index+1 || index < 0) { + return -1; + } + + //避免head发生变化 + ListNode temp = head.next; + while (index-- > 0) { + temp = temp.next; + } + return temp.val; + + } + + public void addAtHead(int val) { + + ListNode need = new ListNode(val); + need.next = head.next; + head.next = need; + size++; + } + + public void addAtTail(int val) { + + ListNode need = new ListNode(val); + ListNode temp = head; + + while (temp.next != null) { + temp = temp.next; + } + + temp.next = need; + size++; + } + + public void addAtIndex(int index, int val) { + + if (index > size || index < 0) { + return; + } + ListNode temp = head; + while (index-- > 0) { + temp = temp.next; + } + + ListNode need = new ListNode(val); + need.next = temp.next; + temp.next = need; + size++; + } + + public void deleteAtIndex(int index) { + + if (index > size-1 || index < 0) { + return; + } + ListNode temp = head; + while (index-- > 0) { + temp = temp.next; + } + + temp.next = temp.next.next; + size--; + } + + public void printList(ListNode head) { + + ListNode temp=head.next; + + while (temp!=null){ + System.out.printf(temp.val+"->"); + temp=temp.next; + } + + System.out.println(); + + + } + + public int getSize() { + + return size; + + } + + + @Test + public void test() { + MyLinkedList1 linkedList = new MyLinkedList1(); + linkedList.addAtHead(1); + printList(linkedList.head); + System.out.println(); + linkedList.addAtTail(3); + printList(linkedList.head); + System.out.println(); + linkedList.addAtIndex(1, 2); //链表变为1-> 2-> 3 + printList(linkedList.head); + System.out.println(); + System.out.println(linkedList.get(1)); +// printList(linkedList.head); + System.out.println(); + linkedList.deleteAtIndex(1); //现在链表是1-> 3 + printList(linkedList.head); + System.out.println(); + System.out.println(linkedList.get(1)); + + + } + + @Test + public void test1() { + MyLinkedList1 linkedList = new MyLinkedList1(); + linkedList.addAtHead(7); + printList(linkedList.head); + + linkedList.addAtHead(2); + printList(linkedList.head); + + linkedList.addAtHead(1); + printList(linkedList.head); + + linkedList.addAtIndex(3, 0); + printList(linkedList.head); + + linkedList.deleteAtIndex(2); + printList(linkedList.head); + + linkedList.addAtHead(6); + printList(linkedList.head); + + linkedList.addAtTail(4); + printList(linkedList.head); + + System.out.println(linkedList.get(4)); + + linkedList.addAtHead(4); + printList(linkedList.head); + + linkedList.addAtIndex(5, 0); + printList(linkedList.head); + + linkedList.addAtHead(6); + printList(linkedList.head); + + +// System.out.println(linkedList.get(1)); +//// printList(linkedList.head); +// System.out.println(); +// linkedList.deleteAtIndex(1); //现在链表是1-> 3 +// printList(linkedList.head); +// System.out.println(); +// System.out.println(linkedList.get(1)); + + + } + + @Test + public void test2() { + MyLinkedList1 linkedList = new MyLinkedList1(); + linkedList.addAtHead(2); + printList(linkedList.head); + + linkedList.deleteAtIndex(1); + printList(linkedList.head); + + linkedList.addAtHead(2); + printList(linkedList.head); + + linkedList.addAtHead(7); + printList(linkedList.head); + + linkedList.addAtHead(3); + printList(linkedList.head); + + linkedList.addAtHead(2); + printList(linkedList.head); + + linkedList.addAtHead(5); + printList(linkedList.head); + + linkedList.addAtTail(5); + printList(linkedList.head); + + System.out.println(linkedList.get(5)); + + linkedList.deleteAtIndex(6); + printList(linkedList.head); + + linkedList.deleteAtIndex(4); + printList(linkedList.head); + + + } + + @Test + public void test3() { + MyLinkedList1 linkedList = new MyLinkedList1(); + linkedList.addAtHead(1); + printList(linkedList.head); + + + linkedList.addAtTail(3); + printList(linkedList.head); + + linkedList.addAtIndex(1, 2); + printList(linkedList.head); + + + System.out.println(linkedList.get(1)); + + linkedList.deleteAtIndex(1); + printList(linkedList.head); + + System.out.println(linkedList.get(1)); + + + } + + @Test + public void test4() { + MyLinkedList1 linkedList = new MyLinkedList1(); + linkedList.addAtHead(4); + printList(linkedList.head); + + System.out.println(linkedList.get(1)); + + linkedList.addAtHead(1); + printList(linkedList.head); + + linkedList.addAtHead(5); + printList(linkedList.head); + + linkedList.deleteAtIndex(3); + printList(linkedList.head); + + linkedList.addAtHead(7); + printList(linkedList.head); + + System.out.println(linkedList.get(3)); + + System.out.println(linkedList.get(3)); + + System.out.println(linkedList.get(3)); + + linkedList.addAtHead(1); + printList(linkedList.head); + + + linkedList.deleteAtIndex(4); + printList(linkedList.head); + + + + + } + + /* + 内存超过99.29%,速度超过30.86% + */ +} + +class ListNode { + public int val; + public ListNode next; + + public ListNode() { + } + + public ListNode(int val) { + this.val = val; + } + + public ListNode(int val, ListNode next) { + this.val = val; + this.next = next; + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/listnode/RemoveElement.java b/Leecode/src/main/java/com/markilue/leecode/listnode/RemoveElement.java new file mode 100644 index 0000000..0f95961 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/listnode/RemoveElement.java @@ -0,0 +1,157 @@ +package com.markilue.leecode.listnode; + +import org.junit.Test; + +/** + * 移除链表元素: + * 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。 + */ +public class RemoveElement { + + + @Test + public void test1() { + ListNode listNode = new ListNode(1); + ListNode listNode2 = new ListNode(2); + ListNode listNode3 = new ListNode(6); + ListNode listNode4 = new ListNode(3); + ListNode listNode5 = new ListNode(4); + ListNode listNode6 = new ListNode(5); + ListNode listNode7 = new ListNode(6); + listNode.next = listNode2; + listNode2.next = listNode3; + listNode3.next = listNode4; + listNode4.next = listNode5; + listNode5.next = listNode6; + listNode6.next = listNode7; + ListNode result = removeElements(listNode, 6); + print(result); + + } + + @Test + public void test2() { + + ListNode listNode = removeElements(null, 1); + print(listNode); + + } + + @Test + public void test3() { + + ListNode listNode = new ListNode(7); + ListNode listNode2 = new ListNode(7); + ListNode listNode3 = new ListNode(7); + ListNode listNode4 = new ListNode(7); + listNode.next = listNode2; + listNode2.next = listNode3; + listNode3.next = listNode4; + + ListNode result = removeElements1(listNode, 7); + print(result); + + } + + + /** + * 内存击败45%,速度击败50% + * @param head + * @param val + * @return + */ + public ListNode removeElements(ListNode head, int val) { + + if (head == null) { + return head; + } + + //创建一个虚拟头节点用于返回 + ListNode listNode = new ListNode(); + listNode.next = head; + ListNode recu = listNode; + + + while (recu.next != null) { + print(listNode); + System.out.println(); + + if (recu.next.val == val) { + recu.next = recu.next.next; + } else { + recu = recu.next; + } + } + + return listNode.next; + + } + + /** + * 改进版,不一定要直接找下一个,可以找下一个不是val的元素 + * 速度还是击败50%,内存击败84% + * @param head + * @param val + * @return + */ + public ListNode removeElements1(ListNode head, int val) { + + if (head == null) { + return head; + } + + //创建一个虚拟头节点用于返回 + ListNode listNode = new ListNode(); + listNode.next = head; + ListNode recu = listNode; + + + while (recu.next != null) { + print(listNode); + System.out.println(); + + if (recu.next.val == val) { + while (recu.next.next!=null&&recu.next.next.val==val){ + recu.next.next=recu.next.next.next; + } + recu.next = recu.next.next; + } else { + recu = recu.next; + } + } + + return listNode.next; + + } + + + public class ListNode { + public int val; + public ListNode next; + + public ListNode() { + } + + public ListNode(int val) { + this.val = val; + } + + public ListNode(int val, ListNode next) { + this.val = val; + this.next = next; + } + } + + public void print(ListNode listNode) { + if (listNode == null) { + System.out.println("链表为空"); + return; + } + while (listNode != null) { + System.out.printf(listNode.val + "->"); + listNode = listNode.next; + } + } + + +}