203 题意:删除链表中等于给定值 val 的所有节点。
示例 1: 输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]
package days0605_60dyas;
public class RrmoveElement {
public static void main(String[] args) {
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(6);
head.next.next.next = new ListNode(3);
head.next.next.next.next = new ListNode(4);
head.next.next.next.next.next = new ListNode(5);
head.next.next.next.next.next.next = new ListNode(6);
head.next.next.next.next.next.next = new ListNode(8);
// 要移除的元素值
int valToRemove = 6;
// 调用 removeElements 方法
ListNode result = removeElements(head, valToRemove);
// 打印结果链表
while (result != null) {
System.out.print(result.val + " ");
result = result.next;
}
}
public static ListNode removeElements(ListNode head, int val) {
if (head == null) {
return head;
}
// 因为删除可能涉及到头节点,所以设置dummy节点,统一操作
ListNode dummy = new ListNode(-1, head);
ListNode pre = dummy;
ListNode cur = head;
while (cur != null) {
if (cur.val == val) {
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
return dummy.next;
}
}
package days0605_60dyas;
public class RemoveElemants2 {
public static void main(String[] args) {
// 创建链表 1 -> 2 -> 6 -> 3 -> 4 -> 5 -> 6
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(6);
head.next.next.next = new ListNode(3);
head.next.next.next.next = new ListNode(4);
head.next.next.next.next.next = new ListNode(5);
head.next.next.next.next.next.next = new ListNode(6);
int valToRemove = 6;
ListNode result = removeElements(head, valToRemove);
// 打印结果链表
while (result != null) {
System.out.print(result.val + " ");
result = result.next;
}
System.out.println("--");
ListNode aa = new ListNode(10);
ListNode heada = new ListNode(1, aa);
aa.next = new ListNode(9);
ListNode res = removeElements(heada, 1);
while (res != null) {
System.out.print(res.val + " ");
res = res.next;
}
}
public static ListNode removeElements(ListNode head, int val) {
while (head != null && head.val == val) {
head = head.next;
}
// 已经为null,提前退出
if (head == null) {
return head;
}
// 已确定当前head.val != val
ListNode pre = head;
ListNode cur = head.next;
while (cur != null) {
if (cur.val == val) {
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
return head;
}
}
class ListNode {
int val;
ListNode next;
ListNode() {
}
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
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
package days0605_60dyas.a;
public class Test {
public static void main(String[] args) {
MyLinkedList list = new MyLinkedList();
// 测试添加节点到头部
list.addAtHead(1);
list.addAtHead(2);
// 测试获取节点值
int valueAtIndex1 = list.get(1);
System.out.println("Value at index 1: " + valueAtIndex1);
// 测试添加节点到尾部
list.addAtTail(3);
list.addAtTail(4);
// 测试在指定位置添加节点
list.addAtIndex(1, 5);
// 测试删除节点
list.deleteAtIndex(2);
// 再次测试获取节点值
int valueAtIndex0 = list.get(0);
System.out.println("Value at index 0 after modifications: " + valueAtIndex0);
// 测试边界情况,如删除头节点
list.deleteAtIndex(0);
int newHeadValue = list.get(0);
System.out.println("New head value after deleting the old head: " + newHeadValue);
// 测试插入到超出链表长度的位置
list.addAtIndex(10, 6);
System.out.println("Size after trying to insert at an out-of-bounds index: " + list.size);
// 测试获取不存在的节点
int invalidIndexValue = list.get(-1);
System.out.println("Value at invalid index (-1): " + invalidIndexValue);
invalidIndexValue = list.get(100);
System.out.println("Value at invalid index (100): " + invalidIndexValue);
}
}
//单链表
class ListNode {
int val;
ListNode next;
ListNode(){}
ListNode(int val) {
this.val=val;
}
}
class MyLinkedList {
//size存储链表元素的个数
int size;
//虚拟头结点
ListNode head;
//初始化链表
public MyLinkedList() {
size = 0;
head = new ListNode(0);
}
//获取第index个节点的数值,注意index是从0开始的,第0个节点就是头结点
public int get(int index) {
//如果index非法,返回-1
if (index < 0 || index >= size) {
return -1;
}
ListNode currentNode = head;
//包含一个虚拟头节点,所以查找第 index+1 个节点
for (int i = 0; i <= index; i++) {
currentNode = currentNode.next;
}
return currentNode.val;
}
//在链表最前面插入一个节点,等价于在第0个元素前添加
public void addAtHead(int val) {
addAtIndex(0, val);
}
//在链表的最后插入一个节点,等价于在(末尾+1)个元素前添加
public void addAtTail(int val) {
addAtIndex(size, val);
}
// 在第 index 个节点之前插入一个新节点,例如index为0,那么新插入的节点为链表的新头节点。
// 如果 index 等于链表的长度,则说明是新插入的节点为链表的尾结点
// 如果 index 大于链表的长度,则返回空
public void addAtIndex(int index, int val) {
if (index > size) {
return;
}
if (index < 0) {
index = 0;
}
size++;
//找到要插入节点的前驱
ListNode pred = head;
for (int i = 0; i < index; i++) {
pred = pred.next;
}
ListNode toAdd = new ListNode(val);
toAdd.next = pred.next;
pred.next = toAdd;
}
//删除第index个节点
public void deleteAtIndex(int index) {
if (index < 0 || index >= size) {
return;
}
size--;
if (index == 0) {
head = head.next;
return;
}
ListNode pred = head;
for (int i = 0; i < index ; i++) {
pred = pred.next;
}
pred.next = pred.next.next;
}
}
206.反转链表
题意:反转一个单链表。
示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
package days0605_60dyas.a;
public class Da1 {
public static void main(String[] args) {
ListNode head = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(3);
ListNode node4 = new ListNode(4);
ListNode node5 = new ListNode(5);
head.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
Da1 da1 = new Da1();
ListNode reversedHead = da1.reverseList(head);
// 打印反转后的链表
ListNode current = reversedHead;
while (current != null) {
System.out.print(current.val + " ");
current = current.next;
}
}
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode cur = head;
ListNode temp = null;
while (cur != null) {
temp = cur.next;//保存下一个节点
cur.next = prev;//反转
prev = cur;//移动prev
cur = temp;//移动cur
}
return prev;
}
}