返回

剖析LeetCode 1598,一步步完善“文件夹操作日志搜集器”

后端

导读:

  • 你是否曾在编程实践中碰壁,却苦于无法理解复杂的代码逻辑?
  • 你是否曾渴望掌握多种语言,跨越语言壁垒,尽情驰骋在计算机科学的广袤天地?

LeetCode 1598的解题历程,将为我们带来编程语言与数据结构的又一次精妙碰撞,让我们一起踏上这趟探索之旅吧!

一、问题的由来

在计算机系统中,文件夹是我们常用的工具,它可以帮助我们有序地整理文件,让文件井然有序。然而,当文件夹数量庞大时,如何有效地管理和记录文件夹的操作就成为了一件颇具挑战的事情。

二、题目概述

LeetCode 1598题目的任务就是设计一个“文件夹操作日志搜集器”,以收集和记录对文件夹的各种操作,比如创建文件夹、删除文件夹、复制文件夹等。这些操作将以日志的形式记录下来,并且我们必须对这些日志进行分析,以回答一些关于文件夹系统的问题。

三、解决之道

要设计一个“文件夹操作日志搜集器”,我们可以使用栈数据结构。栈是一种遵循“先进后出”原则的数据结构,这与文件夹的层级结构非常吻合。当我们创建文件夹时,可以将该文件夹的路径压入栈中;当我们删除文件夹时,可以将该文件夹的路径从栈中弹出;当我们复制文件夹时,可以将该文件夹的路径及其子文件夹的路径都压入栈中。

四、代码实现

为了让大家更好地理解如何使用栈数据结构解决LeetCode 1598的问题,我们提供了三种不同语言——Java、C++和Rust的代码示例。

Java代码:

import java.util.Stack;

class FolderLogCollector {

    private Stack<String> stack;

    public FolderLogCollector() {
        stack = new Stack<>();
    }

    public void createFolder(String path) {
        stack.push(path);
    }

    public void deleteFolder(String path) {
        while (!stack.isEmpty() && !stack.peek().equals(path)) {
            stack.pop();
        }
        if (!stack.isEmpty()) {
            stack.pop();
        }
    }

    public void copyFolder(String path) {
        Stack<String> tempStack = new Stack<>();
        while (!stack.isEmpty() && !stack.peek().equals(path)) {
            tempStack.push(stack.pop());
        }
        if (!stack.isEmpty()) {
            stack.pop();
        }
        while (!tempStack.isEmpty()) {
            stack.push(tempStack.pop());
        }
        stack.push(path);
    }

    public String[] getFolderPaths() {
        String[] paths = new String[stack.size()];
        for (int i = 0; i < paths.length; i++) {
            paths[i] = stack.pop();
        }
        return paths;
    }
}

C++代码:

#include <stack>
#include <vector>

class FolderLogCollector {
private:
    std::stack<std::string> stack;

public:
    FolderLogCollector() {}

    void createFolder(const std::string& path) {
        stack.push(path);
    }

    void deleteFolder(const std::string& path) {
        while (!stack.empty() && stack.top() != path) {
            stack.pop();
        }
        if (!stack.empty()) {
            stack.pop();
        }
    }

    void copyFolder(const std::string& path) {
        std::stack<std::string> tempStack;
        while (!stack.empty() && stack.top() != path) {
            tempStack.push(stack.top());
            stack.pop();
        }
        if (!stack.empty()) {
            stack.pop();
        }
        while (!tempStack.empty()) {
            stack.push(tempStack.top());
            tempStack.pop();
        }
        stack.push(path);
    }

    std::vector<std::string> getFolderPaths() {
        std::vector<std::string> paths;
        while (!stack.empty()) {
            paths.push_back(stack.top());
            stack.pop();
        }
        return paths;
    }
};

Rust代码:

use std::collections::VecDeque;

struct FolderLogCollector {
    stack: VecDeque<String>,
}

impl FolderLogCollector {
    fn new() -> Self {
        Self { stack: VecDeque::new() }
    }

    fn create_folder(&mut self, path: &str) {
        self.stack.push_front(path.to_string());
    }

    fn delete_folder(&mut self, path: &str) {
        while let Some(p) = self.stack.pop_front() {
            if p == path {
                return;
            }
        }
    }

    fn copy_folder(&mut self, path: &str) {
        let mut temp_stack = VecDeque::new();
        while let Some(p) = self.stack.pop_front() {
            if p == path {
                break;
            }
            temp_stack.push_front(p);
        }
        while let Some(p) = temp_stack.pop_front() {
            self.stack.push_front(p);
        }
        self.stack.push_front(path.to_string());
    }

    fn get_folder_paths(&self) -> Vec<String> {
        self.stack.iter().rev().cloned().collect()
    }
}

五、结语

通过LeetCode 1598题目的解题历程,我们不仅掌握了如何使用栈数据结构解决实际问题,还领略了Java、C++和Rust这三种语言的魅力。希望这篇文章能给大家带来启发,让大家在计算机科学的道路上越走越远!