【 剑指offer第2版-第19题-JAVA】

删除链表的节点

题目:在O(1)的时间内删除链表的某一指定节点。给定单向链表的头指针和一个节点指针,定义一个函数在O(1)的时间内删除该节点。

举例:a->b->c->d->e,删除c,结果:a->b->d->e
第一步:先将c节点的下一个节点的值赋值给c节点
a->b->d->d->e
第二步:将赋值后新节点d(原c节点的位置)的指针=原节点d的指针,这样新节点d就指向了原d节点指向的节点。
a->b->d->e
另外注意只有一个节点,和头尾节点删除的临界情况

注意大坑

1.题中并未说明是比较值,还是比较对象(即内存),业务上常规情况都是比较值,如果是比较值,那就需要限制链表中不能有重复值
2.我选择的是比较内存,依旧存在问题,如果不使用构建链表的元素对象,那么就达不到删除元素的目的。也是测试过程中才发现。记录一下
3.总结:学习删除链表的思路,问清楚面试官要求,熟悉链表结构
废话不多说了,上代码。
选择使用值做对比。

/**
     * 找到目标节点的前一个节点,将他的下一个节点替换成目标节点的下一个节点
     * 重点:链表中不能存在重复的值
     * @param head 头节点
     * @param val 目标节点的值
     * @return
     */
    public static LinkedNode deleteNode(LinkedNode head, Integer val) {
        //常规判空
        if(head == null || val == null){
            return null;
        }
        //如果是头节点,则直接返回头节点的下一个节点。
        if(head.getValue() == val){
            return head.getNextNode();
        }
        //目标节点的前一个节点,初始值设为头节点
        LinkedNode pre = head;
        //当前节点,初始值设置为头节点的下一个节点
        LinkedNode cur = head.getNextNode();
        //当前节点不为空且当前节点的值不等于目标节点的值
        while(cur != null && cur.getValue() != val) {
            //将当前节点赋值给pre;
            pre = cur;
            //将当前节点的下一个节点赋值给cur
            cur = cur.getNextNode();
        }
        //此时pre为目标节点的前一个节点
        if(cur != null) {
            pre.setNextNode(cur.getNextNode());
        }
        return head;
    }

选用内存对象对比

public class DeletOneNode {

    public static LinkedNode deletOneNode(LinkedNode root,LinkedNode targetNode){
        //常规判空
        if(root == null || targetNode ==null){
            return null;
        }
        //如果删除的节点不是尾节点
        if(targetNode.getNextNode()!=null){
            //获取到目标节点的下一个节点targetNextNode,使用targetNextNode替换掉targetNode
            LinkedNode targetNextNode = targetNode.getNextNode();
            //先替换值
            targetNode.setValue(targetNextNode.getValue());
            //再替换指针
            targetNode.setNextNode(targetNextNode.getNextNode());
            return root;
        }
        //头节点等于目标节点,且只有一个节点。
        if(root == targetNode){
            return null;
        }
        LinkedNode nextNode = root;
        //尾节点处理
        while(nextNode!=null){
            nextNode = nextNode.getNextNode();
            if(nextNode.getNextNode()==targetNode){
                nextNode.setNextNode(null);
                break;
            }
        }
        return root;
    }

    public static void printNode(LinkedNode node){
        while(node!=null){
            System.out.println(node.getValue());
            node = node.getNextNode();
        }
    }
    public static void main(String[] args) {
        LinkedNode node4 = new LinkedNode(4);
        LinkedNode node3 = new LinkedNode(3,node4);
        LinkedNode node2 = new LinkedNode(2,node3);
        LinkedNode node1 = new LinkedNode(1,node2);
        //测试
        LinkedNode newRootTest= DeletOneNode.deletOneNode(node1,node1);
        DeletOneNode.printNode(newRootTest);


    }
}

数据结构:

public class LinkedNode {
    private int value;
    private LinkedNode nextNode;

    public LinkedNode(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public LinkedNode getNextNode() {
        return nextNode;
    }

    public LinkedNode(int value, LinkedNode nextNode) {
        this.value = value;
        this.nextNode = nextNode;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public void setNextNode(LinkedNode nextNode) {
        this.nextNode = nextNode;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值