题解 | #从单向链表中删除指定值的节点#

从单向链表中删除指定值的节点

https://www.nowcoder.com/practice/f96cd47e812842269058d483a11ced4f

import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNext()) { // 注意 while 处理多个 case
            String str = in.nextLine(); //获得输入
            String[] strs = str.split(" ");  //按空白拆分,方便处理
            int n = Integer.parseInt(strs[0]); //总结点数
            int firstValue = Integer.parseInt(strs[1]); //头节点值
            int aimValue = Integer.parseInt(strs[strs.length - 1]); //目标节点值
            LinkList ll = new LinkList(); //自定义链表
            ll.add(firstValue); //插入头节点
            for (int i = 2; i < strs.length - 1; i += 2) { //插入其他节点
                ll.addNext(Integer.parseInt(strs[i]), Integer.parseInt(strs[i + 1]));
            }
            if (ll.removeNode(aimValue)) { //删除目标节点
                ll.printNodeValue();
            }
            // System.out.println(a + b);
        }
    }


    public static void readLinkList(LinkList lastNode) {

    }

}

class LinkList { //自定义链表类
    int size = 0; //链表长度
    Node headNode; //头节点
    Node tailNode; //尾节点

    LinkList() { //无参构造
    }

    static class Node { //内部节点类
        int value; //节点值
        Node pre; //头指针
        Node curr; //尾指针
        Node(int value, Node pre, Node curr) { //构造
            this.value = value;
            this.pre = pre;
            this.curr = curr;
        }
        Node() {

        }
    }

    public boolean add(int val, int index) { //指定下标插入
        Node newNode = new Node(val, null, null); //新节点
        if (size == 0) { //判空
            headNode = newNode;
            tailNode = newNode;
            size++;
            return true;
        } else if (index < 0 || index > size + 2) { //判下标范围
            return false;
        } else if (index == 1) { //头节点位置直接插入
            newNode.curr = headNode;
            headNode.pre = newNode;
            headNode = newNode;
            size++;
            return true;
        } else if (index == size + 1) { //尾节点位置直接插入
            newNode.pre = tailNode;
            tailNode.curr = newNode;
            tailNode = newNode;
            size++;
            return true;
        } else { //中间位置
            Node preNode = null; //前一个
            Node currNode = headNode;//后一个(注意前后是挨着的,preNode->currNode)
            for (int i = 2; i <= index; i++) { //获得指定下标位置的节点currNode
                preNode = currNode;
                currNode = currNode.curr;
            }
            newNode.pre = preNode; 
            newNode.curr = currNode;
            preNode.curr = newNode;
            currNode.pre = newNode;//插入操作
            size++; //长度增加
            return true;
        }
    }
    public void add(int val) { //尾插法插入节点
        Node newNode = new Node(val, null, null);
        if (size == 0) { //判空
            headNode = newNode;
            tailNode = newNode;
            size++;
        } else {
            newNode.pre = tailNode;
            tailNode.curr = newNode;
            tailNode = newNode;
            size++;
        }
    }

    public boolean addNext(int val, int pre) { //题中指定插入方法,插入指定值的节点后面
        Node newNode = new Node(val, null, null);
        if (size == 0) { //判空
            return false;
        }
        Node preNode = null;
        Node currNode = headNode;
        for (int i = 0; i < size; i++) { //遍历链表找指定值节点
            if (currNode.value == pre) { //找到后处理
                newNode.pre = currNode;
                if (currNode.curr == null) { //判断是否为尾节点
                    currNode.curr = newNode;
                    size++;
                    return true;
                } else { //其他情况
                    newNode.curr = currNode.curr;
                    currNode.curr = newNode;
                    currNode = newNode;
                    size++;
                    return true;
                }
            }
            preNode = currNode;
            currNode = currNode.curr;
        }
        return  false;
    }

    public void printNodeValue() { //遍历链表并打印节点
        Node preNode = null;
        Node currNode = headNode;
        while (currNode.curr != null) {
            System.out.print(currNode.value + " ");
            preNode = currNode;
            currNode = currNode.curr;
        }
        System.out.print(currNode.value + "");
    }

    public boolean removeNode(int val) { //删除节点
        Node preNode = null;
        Node currNode = headNode;
        for (int i = 0; i < size; i++) { //遍历链表找节点
            if (currNode.value == val) { //找到处理
                if (currNode.pre == null) { //头节点
                    headNode = currNode.curr;
                    size--;
                    return true;
                } else if (currNode.curr == null) { //尾节点
                    currNode.pre.curr = null;
                    size--;
                    return true;
                } else { //其他情况
                    preNode.curr = currNode.curr;
                    currNode.curr.pre = preNode;
                    size--;
                    return true;
                }
            }
            preNode = currNode;
            currNode = currNode.curr;
        }
        return false;
    }
}

手搓链表

全部评论

相关推荐

点赞 评论 收藏
分享
点赞 评论 收藏
分享
无敌虾孝子:喜欢爸爸还是喜欢妈妈
点赞 评论 收藏
分享
评论
点赞
1
分享
牛客网
牛客企业服务