LeetCode203 707链表
- 双向链表的使用 - 增加虚拟头节点方便操作
This commit is contained in:
parent
c707fd4ca2
commit
9385b628ad
186
src/main/java/cn/whaifree/leetCode/easy/LeetCode203.java
Normal file
186
src/main/java/cn/whaifree/leetCode/easy/LeetCode203.java
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
package cn.whaifree.leetCode.easy;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.whaifree.leetCode.model.ListNode;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 链表
|
||||||
|
*
|
||||||
|
* 203. 移除链表元素
|
||||||
|
* 示例 1:
|
||||||
|
|
||||||
|
* 输入:head = [1,2,6,3,4,5,6], val = 6
|
||||||
|
* 输出:[1,2,3,4,5]
|
||||||
|
* 示例 2:
|
||||||
|
*
|
||||||
|
* 输入:head = [], val = 1
|
||||||
|
* 输出:[]
|
||||||
|
* 示例 3:
|
||||||
|
*
|
||||||
|
* 输入:head = [7,7,7,7], val = 7
|
||||||
|
* 输出:[]
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class LeetCode203 {
|
||||||
|
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * [6] 6
|
||||||
|
// * [] 6
|
||||||
|
// * [2] 6
|
||||||
|
// *
|
||||||
|
// *
|
||||||
|
// * @param head
|
||||||
|
// * @param val
|
||||||
|
// * @return
|
||||||
|
// */
|
||||||
|
// public ListNode removeElements(ListNode head, int val) {
|
||||||
|
//
|
||||||
|
// // 如果链表只有一个节点或者没有要删除的元素,则直接返回原链表
|
||||||
|
// if (head == null) {
|
||||||
|
// return head;
|
||||||
|
// }
|
||||||
|
// if (head.next == null && head.val == val) {
|
||||||
|
// head = null;
|
||||||
|
// return head;
|
||||||
|
// } else if (head.next == null) {
|
||||||
|
// return head;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 定义一个指针pre指向head节点
|
||||||
|
// // 定义一个指针index指向head.next节点
|
||||||
|
// ListNode pre = head;
|
||||||
|
// ListNode index = head.next;
|
||||||
|
//
|
||||||
|
// // 遍历链表,直到index.next为null
|
||||||
|
// while (index.next != null) {
|
||||||
|
//
|
||||||
|
// // 如果index节点的值等于要删除的元素val
|
||||||
|
// if (index.val == val) {
|
||||||
|
//
|
||||||
|
// // 删除该节点
|
||||||
|
// pre.next = index.next;
|
||||||
|
//
|
||||||
|
// // 将指针index移动到下一个节点
|
||||||
|
// index = pre.next;
|
||||||
|
//
|
||||||
|
// // 将指针pre移动到下一个节点
|
||||||
|
// pre = pre.next;
|
||||||
|
//
|
||||||
|
// // 继续遍历链表
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 如果index节点的值不等于要删除的元素val
|
||||||
|
// index = index.next;
|
||||||
|
// pre = pre.next;
|
||||||
|
// }
|
||||||
|
// // 尾巴节点为val,那就删除尾巴节点
|
||||||
|
// if (index.val == val) {
|
||||||
|
// pre.next = null;
|
||||||
|
// }
|
||||||
|
// // 如果头节点的值等于要删除的元素val
|
||||||
|
// if (head.val == val) {
|
||||||
|
// head = head.next;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// // 返回删除元素后的链表
|
||||||
|
// return head;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
public ListNode removeElements1(ListNode head, int val) {
|
||||||
|
// 找到第一个head不删除的点 删除头结点时另做考虑
|
||||||
|
while (head != null && head.val == val) {
|
||||||
|
head = head.next;
|
||||||
|
}
|
||||||
|
// 保证删完后不为空
|
||||||
|
if(head==null)
|
||||||
|
return head;
|
||||||
|
//
|
||||||
|
ListNode index = head;
|
||||||
|
|
||||||
|
while (index.next != null) {
|
||||||
|
if (index.next.val == val) {
|
||||||
|
index.next = index.next.next;
|
||||||
|
} else {
|
||||||
|
index = index.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 递归
|
||||||
|
// * @param head
|
||||||
|
// * @param val
|
||||||
|
// * @return
|
||||||
|
// */
|
||||||
|
// public ListNode removeElements(ListNode head, int val) {
|
||||||
|
// if (head == null) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// head.next = removeElements(head.next, val);
|
||||||
|
// if (head.next.val == val) {
|
||||||
|
// return head.next.next;
|
||||||
|
// } else {
|
||||||
|
// return head.next;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归
|
||||||
|
* 1. 停止条件
|
||||||
|
* 2. 循环返回值
|
||||||
|
* @param head
|
||||||
|
* @param val
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ListNode removeElements(ListNode head, int val) {
|
||||||
|
if (head == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// h
|
||||||
|
// 6 6
|
||||||
|
// 让head 之后的元素交给下个递归
|
||||||
|
head.next = removeElements(head.next, val);
|
||||||
|
if (head.val == val) {
|
||||||
|
return head.next;
|
||||||
|
} else {
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 递归的返回值为head.next,即传入的下一结点;
|
||||||
|
// 如果匹配就返回当前结点;不匹配,返回的head就是前一结点了。
|
||||||
|
// 压栈时的head.next为后一个结点;弹栈时的head.next就位后前一个结点
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListNode removeElements3(ListNode head, int val) {
|
||||||
|
if (head == null) {
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 获取当前节点
|
||||||
|
// 2. 递归next 6 6
|
||||||
|
head.next = removeElements3(head.next, val);
|
||||||
|
if (head.val == val) {
|
||||||
|
return head.next;
|
||||||
|
} else {
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void Test() {
|
||||||
|
ListNode listNode = ListNode.listNodeFromArray(new int[]{6,6,6,6});
|
||||||
|
// ListNode.printList(listNode);
|
||||||
|
ListNode listNode1 = removeElements(listNode, 6);
|
||||||
|
ListNode.printList(listNode1);
|
||||||
|
}
|
||||||
|
}
|
@ -74,13 +74,81 @@ public class LeetCode54 {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间复杂度:O(mn)O(mn)O(mn),其中 mmm 和 nnn 分别是输入矩阵的行数和列数。矩阵中的每个元素都要被访问一次。
|
||||||
|
*
|
||||||
|
* 空间复杂度:O(1)O(1)O(1)。除了输出数组以外,空间复杂度是常数。
|
||||||
|
*
|
||||||
|
* @param matrix
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
|
||||||
|
public List<Integer> spiralOrder1(int[][] matrix) {
|
||||||
|
int width = matrix[0].length;
|
||||||
|
int height = matrix.length;
|
||||||
|
List<Integer> s = new ArrayList<>(width * height);
|
||||||
|
|
||||||
|
if (height == 1) {
|
||||||
|
int[] line = matrix[0];
|
||||||
|
for (int i : line) {
|
||||||
|
s.add(i);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
} else if (width == 1) {
|
||||||
|
for (int[] ints : matrix) {
|
||||||
|
s.add(ints[0]);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
int loop = Math.min(width, height) / 2;
|
||||||
|
int start = 0;
|
||||||
|
int i = 0, j = 0;
|
||||||
|
while (start < loop) {
|
||||||
|
|
||||||
|
for (i = start; i < width - start - 1; i++) {
|
||||||
|
s.add(matrix[start][i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = start; j < height - start - 1; j++) {
|
||||||
|
s.add(matrix[j][i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i >= start + 1; i--) {
|
||||||
|
s.add(matrix[j][i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; j >= start + 1; j--) {
|
||||||
|
s.add(matrix[j][i]);
|
||||||
|
}
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width > height) {
|
||||||
|
if (height % 2 == 1) {
|
||||||
|
// 横向填充
|
||||||
|
for (; i < width - start-1; i++) {
|
||||||
|
s.add(matrix[start][i + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (width % 2 == 1) {
|
||||||
|
for (; j < height - start - 1; j++) {
|
||||||
|
s.add(matrix[j+1][i + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
|
||||||
|
}
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
spiralOrder(new int[][]{
|
spiralOrder1(new int[][]{
|
||||||
{1,2,4},
|
{1,2},
|
||||||
{5,6,8},
|
{1,3},
|
||||||
{9,10,12}
|
{1,3}
|
||||||
|
|
||||||
}).forEach(System.out::println);
|
}).forEach(System.out::println);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
267
src/main/java/cn/whaifree/leetCode/middle/LeetCode707.java
Normal file
267
src/main/java/cn/whaifree/leetCode/middle/LeetCode707.java
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
package cn.whaifree.leetCode.middle;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 707. 设计链表
|
||||||
|
* 中等
|
||||||
|
* 相关标签
|
||||||
|
* 相关企业
|
||||||
|
* 你可以选择使用单链表或者双链表,设计并实现自己的链表。
|
||||||
|
*
|
||||||
|
* 单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。
|
||||||
|
*
|
||||||
|
* 如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。
|
||||||
|
*
|
||||||
|
* 实现 MyLinkedList 类:
|
||||||
|
*
|
||||||
|
* MyLinkedList() 初始化 MyLinkedList 对象。
|
||||||
|
* int get(int index) 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1 。
|
||||||
|
* void addAtHead(int val) 将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。
|
||||||
|
* void addAtTail(int val) 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。
|
||||||
|
* void addAtIndex(int index, int val) 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。
|
||||||
|
* void deleteAtIndex(int index) 如果下标有效,则删除链表中下标为 index 的节点。
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 示例:
|
||||||
|
*
|
||||||
|
* 输入
|
||||||
|
* ["MyLinkedList", "addAtHead", "addAtTail", "addAtIndex", "get", "deleteAtIndex", "get"]
|
||||||
|
* [[], [1], [3], [1, 2], [1], [1], [1]]
|
||||||
|
* 输出
|
||||||
|
* [null, null, null, null, 2, null, 3]
|
||||||
|
*
|
||||||
|
* 解释
|
||||||
|
* MyLinkedList myLinkedList = new MyLinkedList();
|
||||||
|
* myLinkedList.addAtHead(1);
|
||||||
|
* myLinkedList.addAtTail(3);
|
||||||
|
* myLinkedList.addAtIndex(1, 2); // 链表变为 1->2->3
|
||||||
|
* myLinkedList.get(1); // 返回 2
|
||||||
|
* myLinkedList.deleteAtIndex(1); // 现在,链表变为 1->3
|
||||||
|
* myLinkedList.get(1); // 返回 3
|
||||||
|
*/
|
||||||
|
public class LeetCode707 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
MyLinkedList myLinkedList = new MyLinkedList();
|
||||||
|
myLinkedList.addAtHead(4);
|
||||||
|
myLinkedList.get(1);
|
||||||
|
myLinkedList.addAtHead(1);
|
||||||
|
myLinkedList.addAtHead(5);
|
||||||
|
myLinkedList.deleteAtIndex(3);
|
||||||
|
myLinkedList.addAtHead(7);
|
||||||
|
myLinkedList.get(3);
|
||||||
|
myLinkedList.get(3);
|
||||||
|
myLinkedList.get(3);
|
||||||
|
|
||||||
|
myLinkedList.addAtHead(1);
|
||||||
|
myLinkedList.deleteAtIndex(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class ListNode1{
|
||||||
|
int val;
|
||||||
|
ListNode1 next;
|
||||||
|
|
||||||
|
public ListNode1() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListNode1(int val, ListNode1 next) {
|
||||||
|
this.val = val;
|
||||||
|
this.next = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过了 但效果不好
|
||||||
|
*
|
||||||
|
* 执行用时分布11ms
|
||||||
|
* 击败12.61%使用 Java 的用户
|
||||||
|
*
|
||||||
|
* 消耗内存分布44.49MB
|
||||||
|
* 击败5.02%使用 Java 的用户
|
||||||
|
*/
|
||||||
|
class MyLinkedList1 {
|
||||||
|
|
||||||
|
ListNode1 head;
|
||||||
|
public MyLinkedList1() {
|
||||||
|
head = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0
|
||||||
|
public int get(int index) {
|
||||||
|
if (index < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ListNode1 node = head;
|
||||||
|
int i = 0;
|
||||||
|
while (node != null) {
|
||||||
|
if (i++ == index) {
|
||||||
|
return node.val;
|
||||||
|
}
|
||||||
|
node = node.next;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAtHead(int val) {
|
||||||
|
head = new ListNode1(val, head);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAtTail(int val) {
|
||||||
|
if (head == null) {
|
||||||
|
head = new ListNode1(val, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ListNode1 node = head;
|
||||||
|
while (node.next != null) {
|
||||||
|
node = node.next;
|
||||||
|
}
|
||||||
|
node.next = new ListNode1(val, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAtIndex(int index, int val) {
|
||||||
|
if (index == 0) {
|
||||||
|
addAtHead(val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ListNode1 node = head;
|
||||||
|
int i = 0;
|
||||||
|
while (node != null) {
|
||||||
|
if (i++ == index - 1) {
|
||||||
|
node.next = new ListNode1(val, node.next);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
node = node.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteAtIndex(int index) {
|
||||||
|
if (index == 0) {
|
||||||
|
// 头删
|
||||||
|
head = head.next;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ListNode1 node = head;
|
||||||
|
int i = 0;
|
||||||
|
while (node != null) {
|
||||||
|
if (i++ == index - 1 && node.next != null) {
|
||||||
|
node.next = node.next.next;
|
||||||
|
}
|
||||||
|
node = node.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ListNode{
|
||||||
|
int val;
|
||||||
|
ListNode next;
|
||||||
|
|
||||||
|
public ListNode() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListNode(int val, ListNode next) {
|
||||||
|
this.val = val;
|
||||||
|
this.next = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行用时分布9ms
|
||||||
|
* 击败88.60%使用 Java 的用户
|
||||||
|
*
|
||||||
|
* 消耗内存分布44.44MB
|
||||||
|
* 击败5.02%使用 Java 的用户
|
||||||
|
*/
|
||||||
|
class MyLinkedList {
|
||||||
|
|
||||||
|
int size;
|
||||||
|
ListNode head;
|
||||||
|
|
||||||
|
public MyLinkedList() {
|
||||||
|
head = null;
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int get(int index) {
|
||||||
|
if (index < 0 || index > size - 1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ListNode node = head;
|
||||||
|
for (int i = 0; i < index; i++) {
|
||||||
|
node = node.next;
|
||||||
|
}
|
||||||
|
return node.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAtHead(int val) {
|
||||||
|
head = new ListNode(val, head);
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAtTail(int val) {
|
||||||
|
addAtIndex(size, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAtIndex(int index, int val) {
|
||||||
|
if (index == 0) {
|
||||||
|
// 头插
|
||||||
|
head = new ListNode(val, head);
|
||||||
|
size++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (index < 0 || index > size) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListNode node = head;
|
||||||
|
int i = 0;
|
||||||
|
while (i++ < index - 1) {
|
||||||
|
node = node.next;
|
||||||
|
}
|
||||||
|
node.next = new ListNode(val, node.next);
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteAtIndex(int index) {
|
||||||
|
if (index < 0 || index > size - 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (index == 0) {
|
||||||
|
// 头删
|
||||||
|
head = head.next;
|
||||||
|
size--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListNode node = head;
|
||||||
|
int i = 0;
|
||||||
|
while (i++ < index - 1) {
|
||||||
|
node = node.next;
|
||||||
|
}
|
||||||
|
node.next = node.next.next;
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
*/
|
49
src/main/java/cn/whaifree/leetCode/model/ListNode.java
Normal file
49
src/main/java/cn/whaifree/leetCode/model/ListNode.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package cn.whaifree.leetCode.model;
|
||||||
|
|
||||||
|
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 static ListNode listNodeFromArray(int[] nums) {
|
||||||
|
if (nums == null || nums.length == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListNode dummy = new ListNode(0);
|
||||||
|
ListNode head = dummy;
|
||||||
|
ListNode prev = dummy;
|
||||||
|
|
||||||
|
for (int num : nums) {
|
||||||
|
ListNode node = new ListNode(num);
|
||||||
|
prev.next = node;
|
||||||
|
prev = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dummy.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出链表的函数
|
||||||
|
* @param head 链表的头节点
|
||||||
|
*/
|
||||||
|
public static void printList(ListNode head) {
|
||||||
|
ListNode curr = head;
|
||||||
|
while (curr != null) {
|
||||||
|
System.out.print(curr.val + " ");
|
||||||
|
curr = curr.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user