面试题18. 删除链表的节点

题目

给定单向链表的头指针和一个要删除的节点,定义一个函数删除该节点。
示例
输入:head = [4,5,1,9] ,val = 5
输出:[4,1,9]
题目中链表节点值互不相同

解题思路

两种方法,原理都差不多,定为节点,删除引用。即都是通过找val的节点,然后将val前一个节点的next指向val这个节点的next。

方法一:单指针,算法流程:

  • 特例处理:当应该删除头结点时,直接返回head.next即可;
  • 初始化:定义一个 list = head ;
  • 定位节点:当list.next为空 或 list.next.val等于val时,跳出循环;循环里面,list = list.next,然后遍历下一个节点;
  • 删除节点:若list.next.val 等于val,并且list.next 不等于空时,list.next = list.next.next;
  • 返回值:返回head即可。

方法二:双指针,算法流程:

  • 特例处理:当应该删除头结点时,直接返回head.next即可;
  • 初始化:定义两个listNode, pre= head ,cur = head.next;
  • 定位节点:当cur为空或curd的值等于val时跳出循环,循环里面,cur保存当前节点,pre = cur,cur = cur.next;
  • 删除节点:若cur指向要删除的节点值val,则执行pre.next = cur.nex,若cur为空,表示链表中不包含值为val这个节点;
  • 返回值:返回head即可。

复杂度

两个算法的复杂度都是一样的,时间复杂度最差为O(N),空间复杂度为O(1)。

代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {

    /************************ 双指针 ****************************/
    public ListNode deleteNode1(ListNode head, int val) {
        if(head == null) return head;
        if(head.val == val) return head.next;
        ListNode list = new ListNode();
        list = head;
        while(list.next != null && list.next.val != val){
            list = list.next;
        }
        if(list != null)list.next = list.next.next;
        return head;
    }

    /************************ 单指针 ****************************/
    public ListNode deleteNode(ListNode head, int val) {
        if(head == null) return head;
        if(head.val == val) return head.next;
        ListNode pre = head , cur = head.next;
        while(cur != null && cur.val != val){
            pre = cur;
            cur = cur.next;
        }
        if(cur != null) pre.next = cur.next;
        return head;
    }
}

你可能感兴趣的:(剑指offer,链表,java)