题目描述
题目一:在O(1)时间内删除链表节点
给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点。
lc-题目参数不同
实现-lc
- 参考
时间复杂度 O(N) : N 为链表长度,删除操作平均需循环 N/2 次,最差 N 次。
空间复杂度 O(1) : cur, pre 占用常数大小额外空间。
public ListNode deleteNode(ListNode head, int val) {
if (head.val == val) return head.next;
ListNode pre = head; // 双指针
ListNode cur = head.next;
while (cur != null && cur.val != val) {
pre = cur;
cur = cur.next;
}
if (cur != null) { // cur被cur.next替换
pre.next = cur.next;
}
return head;
}
实现
/**面试18.1 删除链表节点
* 在O(1)时间内删除链表节点
*/
public class C18_list_DeleteListNode {
public static class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
static class Solution{
public static void deleteListNode(ListNode head,ListNode toDelete){
if(head==null||toDelete==null){
return;
}
if(head==toDelete){ //1.只有一个节点
head =null;
} else if(toDelete.next!=null){//2.要删除的节点不是尾节点
ListNode tmp =toDelete.next; //toDelete1 -> tmp -> tmp.next
toDelete.val=tmp.val; //toDelete1 = tmp
toDelete.next=tmp.next; //删除tmp
tmp=null; // null toDetete2(tmp)->toDetete2.next
}else { //3.链表中多个节点,删掉尾节点
ListNode node =head;
while (node.next!=toDelete){
node=node.next;
}
node.next=null;
//toDelete=null;
}
}
}
Test
public static void main(String[] args) {
ListNode node1 = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(3);
node1.next = node2;
node2.next = node3;
ListNode head = node1;
while (head != null) {
System.out.print(head.val);
head = head.next;
}
System.out.println();
System.out.println("-----------");
Solution solution = new Solution();
solution.deleteListNode(node1, node2);
ListNode node=node1;
while (node != null) {
System.out.print(node.val);
node = node.next;
}
}
lc实现
lc的题目 参数稍有不同
方法1:更高效的解法
public ListNode deleteNode(ListNode head, int val) {
if(head.val == val)
return head.next;
ListNode p1 = head, p2 = head.next;
while(p2 != null && p2.val != val) {
p1 = p2;
p2 = p2.next;
}
//找到了 =val 的位置
if(p2 != null)
p1.next = p2.next;
return head;
}
// https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/solution/mian-shi-ti-18-shan-chu-lian-biao-de-jie-dian-sh-2/
方法2:jz思路
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:38 MB, 在所有 Java 提交中击败了26.67%的用户
public ListNode deleteNode(ListNode head, int val) {
if (head == null) return null;
if (head.val == val) { //1 头:删除的
head = head.next;
}
//从第2个开始遍历
ListNode node = head;
while (node != null && node.next != null) {
if (node.next.val == val) { //2 中间:删除中间的
if (node.next.next != null) {
node.next = node.next.next;
// node.next.val = node.next.val; 不需要这句
} else { //3 尾:删除最后一个
node.next = null;
}
}
node = node.next;
}
return head;
}