牛客题解 | 【模板】链表

题目## 题目

题目链接

解题思路

  1. 插入操作

    • 创建一个新节点。
    • 如果链表为空,直接将新节点作为头节点。
    • 遍历链表,找到第一个值为 x 的节点,在其前插入新节点。
    • 如果没有找到 x,将新节点插入到链表末尾。
  2. 删除操作

    • 如果链表为空,直接返回。
    • 如果头节点的值为 x,直接删除头节点。
    • 遍历链表,找到第一个值为 x 的节点,删除该节点。
  3. 输出链表

    • 遍历链表输出每个节点的值。
    • 如果链表为空,输出 “NULL”。

代码

#include <iostream>
#include <string>
using namespace std;

struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(nullptr) {}
};

class LinkedList {
private:
    ListNode* head;

public:
    LinkedList() : head(nullptr) {}

    void insert(int x, int y) {
        ListNode* newNode = new ListNode(y);
        if (!head) {
            head = newNode;
            return;
        }

        if (head->val == x) {
            newNode->next = head;
            head = newNode;
            return;
        }

        ListNode* prev = nullptr;
        ListNode* curr = head;
        while (curr && curr->val != x) {
            prev = curr;
            curr = curr->next;
        }

        if (prev) {
            newNode->next = prev->next;
            prev->next = newNode;
        } else {
            newNode->next = head;
            head = newNode;
        }
    }

    void deleteNode(int x) {
        if (!head) return;

        if (head->val == x) {
            ListNode* temp = head;
            head = head->next;
            delete temp;
            return;
        }

        ListNode* prev = nullptr;
        ListNode* curr = head;
        while (curr && curr->val != x) {
            prev = curr;
            curr = curr->next;
        }

        if (curr) {
            prev->next = curr->next;
            delete curr;
        }
    }

    void printList() {
        if (!head) {
            cout << "NULL" << endl;
            return;
        }

        ListNode* curr = head;
        while (curr) {
            cout << curr->val << " ";
            curr = curr->next;
        }
        cout << endl;
    }
};

int main() {
    int n;
    cin >> n;
    LinkedList list;

    string op;
    while (n--) {
        cin >> op;
        if (op == "insert") {
            int x, y;
            cin >> x >> y;
            list.insert(x, y);
        } else if (op == "delete") {
            int x;
            cin >> x;
            list.deleteNode(x);
        }
    }

    list.printList();
    return 0;
}
import java.util.Scanner;

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}

class LinkedList {
    private ListNode head;

    public LinkedList() {
        head = null;
    }

    public void insert(int x, int y) {
        ListNode newNode = new ListNode(y);
        if (head == null) {
            head = newNode;
            return;
        }

        if (head.val == x) {
            newNode.next = head;
            head = newNode;
            return;
        }

        ListNode prev = null;
        ListNode curr = head;
        while (curr != null && curr.val != x) {
            prev = curr;
            curr = curr.next;
        }

        if (prev != null) {
            newNode.next = prev.next;
            prev.next = newNode;
        } else {
            newNode.next = head;
            head = newNode;
        }
    }

    public void deleteNode(int x) {
        if (head == null) return;

        if (head.val == x) {
            head = head.next;
            return;
        }

        ListNode prev = null;
        ListNode curr = head;
        while (curr != null && curr.val != x) {
            prev = curr;
            curr = curr.next;
        }

        if (curr != null) {
            prev.next = curr.next;
        }
    }

    public void printList() {
        if (head == null) {
            System.out.println("NULL");
            return;
        }

        ListNode curr = head;
        while (curr != null) {
            System.out.print(curr.val + " ");
            curr = curr.next;
        }
        System.out.println();
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        LinkedList list = new LinkedList();

        for (int i = 0; i < n; i++) {
            String op = sc.next();
            if (op.equals("insert")) {
                int x = sc.nextInt();
                int y = sc.nextInt();
                list.insert(x, y);
            } else if (op.equals("delete")) {
                int x = sc.nextInt();
                list.deleteNode(x);
            }
        }

        list.printList();
    }
}
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None

    def insert(self, x, y):
        new_node = ListNode(y)
        if not self.head:
            self.head = new_node
            return

        if self.head.val == x:
            new_node.next = self.head
            self.head = new_node
            return

        prev = None
        curr = self.head
        while curr and curr.val != x:
            prev = curr
            curr = curr.next

        if prev:
            new_node.next = prev.next
            prev.next = new_node
        else:
            new_node.next = self.head
            self.head = new_node

    def delete(self, x):
        if not self.head:
            return

        if self.head.val == x:
            self.head = self.head.next
            return

        prev = None
        curr = self.head
        while curr and curr.val != x:
            prev = curr
            curr = curr.next

        if curr:
            prev.next = curr.next

    def print_list(self):
        if not self.head:
            print("NULL")
            return

        curr = self.head
        while curr:
            print(curr.val, end=" ")
            curr = curr.next
        print()

# 读取输入
n = int(input())
linked_list = LinkedList()

for _ in range(n):
    op = input().strip().split()
    if op[0] == "insert":
        x, y = int(op[1]), int(op[2])
        linked_list.insert(x, y)
    elif op[0] == "delete":
        x = int(op[1])
        linked_list.delete(x)

linked_list.print_list()

算法及复杂度分析

算法:

  • 链表的基本操作

时间复杂度:

  • 插入操作(insert): O ( n ) \mathcal{O}(n) O(n)

    • 需要遍历链表找到插入位置
    • 最坏情况下需要遍历整个链表
  • 删除操作(delete): O ( n ) \mathcal{O}(n) O(n)

    • 需要遍历链表找到要删除的节点
    • 最坏情况下需要遍历整个链表
  • 打印操作(print_list): O ( n ) \mathcal{O}(n) O(n)

    • 需要遍历整个链表输出所有节点
  • 总体时间复杂度: O ( q n ) \mathcal{O}(qn) O(qn)

    • q q q 是操作次数
    • n n n 是链表长度
    • 每个操作最坏情况下都需要遍历整个链表

空间复杂度:

  • 链表存储: O ( n ) \mathcal{O}(n) O(n)

    • n n n 是链表的节点数
    • 每个节点需要存储值和指针
  • 其他变量: O ( 1 ) \mathcal{O}(1) O(1)

    • 只需要少量额外变量来处理操作
  • 总体空间复杂度: O ( n ) \mathcal{O}(n) O(n)

    • 主要由链表本身的存储空间决定

题目链接

解题思路

  1. 使用一个固定大小的数组来存储队列元素。
  2. 维护两个指针 headtail,分别指向队首和队尾。
  3. push 操作:将元素加入队尾,更新 tail 指针。
  4. pop 操作:输出并移除队首元素,更新 head 指针。
  5. front 操作:输出队首元素。
  6. 检查队列是否满或空,以决定是否输出 “full” 或 “empty”。

代码

#include <iostream>
#include <vector>
#include <string>
using namespace std;

class CircularQueue {
private:
    vector<int> data;
    int head, tail, size, capacity;

public:
    CircularQueue(int n) : data(n), head(0), tail(0), size(0), capacity(n) {}

    void push(int x) {
        if (size == capacity) {
            cout << "full\n";
        } else {
            data[tail] = x;
            tail = (tail + 1) % capacity;
            size++;
        }
    }

    void pop() {
        if (size == 0) {
            cout << "empty\n";
        } else {
            cout << data[head] << "\n";
            head = (head + 1) % capacity;
            size--;
        }
    }

    void front() {
        if (size == 0) {
            cout << "empty\n";
        } else {
            cout << data[head] << "\n";
        }
    }
};

int main() {
    int n, q;
    cin >> n >> q;
    CircularQueue cq(n);

    string op;
    while (q--) {
        cin >> op;
        if (op == "push") {
            int x;
            cin >> x;
            cq.push(x);
        } else if (op == "pop") {
            cq.pop();
        } else if (op == "front") {
            cq.front();
        }
    }
    return 0;
}
import java.util.Scanner;

class CircularQueue {
    private int[] data;
    private int head, tail, size, capacity;

    public CircularQueue(int n) {
        data = new int[n];
        head = 0;
        tail = 0;
        size = 0;
        capacity = n;
    }

    public void push(int x) {
        if (size == capacity) {
            System.out.println("full");
        } else {
            data[tail] = x;
            tail = (tail + 1) % capacity;
            size++;
        }
    }

    public void pop() {
        if (size == 0) {
            System.out.println("empty");
        } else {
            System.out.println(data[head]);
            head = (head + 1) % capacity;
            size--;
        }
    }

    public void front() {
        if (size == 0) {
            System.out.println("empty");
        } else {
            System.out.println(data[head]);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int q = sc.nextInt();
        CircularQueue cq = new CircularQueue(n);

        for (int i = 0; i < q; i++) {
            String op = sc.next();
            if (op.equals("push")) {
                int x = sc.nextInt();
                cq.push(x);
            } else if (op.equals("pop")) {
                cq.pop();
            } else if (op.equals("front")) {
                cq.front();
            }
        }
    }
}
class CircularQueue:
    def __init__(self, n):
        self.data = [0] * n
        self.head = 0
        self.tail = 0
        self.size = 0
        self.capacity = n

    def push(self, x):
        if self.size == self.capacity:
            print("full")
        else:
            self.data[self.tail] = x
            self.tail = (self.tail + 1) % self.capacity
            self.size += 1

    def pop(self):
        if self.size == 0:
            print("empty")
        else:
            print(self.data[self.head])
            self.head = (self.head + 1) % self.capacity
            self.size -= 1

    def front(self):
        if self.size == 0:
            print("empty")
        else:
            print(self.data[self.head])

# 读取输入
n, q = map(int, input().split())
cq = CircularQueue(n)

for _ in range(q):
    op = input().strip()
    if op.startswith("push"):
        _, x = op.split()
        cq.push(int(x))
    elif op == "pop":
        cq.pop()
    elif op == "front":
        cq.front()

算法及复杂度分析

  • 算法:循环队列的基本操作
  • 时间复杂度: O ( 1 ) \mathcal{O}(1) O(1) 对于每个操作。
  • 空间复杂度: O ( n ) \mathcal{O}(n) O(n),其中 n n n 是队列的容量。

这个问题考察了循环队列的实现,重点在于正确维护 headtail 指针的移动和边界条件的处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值