【2024华为OD-E卷-200分-目录删除】(题目+思路+Java&C++&Python解析)

题目

题目描述

给定一个文件系统目录结构,该结构以字符串数组的形式表示,每个字符串表示一个文件或目录的路径。你需要删除指定的目录,并返回删除后的目录结构。如果目录不存在或目录不为空,则无需删除并返回原始目录结构。

输入

  • paths: 一个字符串数组,表示文件系统的目录结构。
  • dir: 需要删除的目录路径。

输出

  • 删除指定目录后的文件系统目录结构,如果目录不存在或不为空,则返回原始目录结构。

示例

输入:
paths = ["a/","a/b/","c/d/","c/d/e/","c/f/"]
dir = "a/b/"
输出:
["a/","c/d/","c/d/e/","c/f/"]

输入:
paths = ["a/","a/b/","c/d/","c/d/e/","c/f/"]
dir = "c/d/"
输出:
["a/","a/b/"]

思路

  1. 构建目录树:首先,我们需要将输入的路径数组转换为一个目录树结构,以便能够方便地判断目录是否存在以及是否为空。
  2. 检查目录:检查需要删除的目录是否存在以及是否为空。
  3. 删除目录:如果目录存在且为空,则删除该目录及其父目录中的引用。
  4. 重建路径数组:根据修改后的目录树结构,重新生成路径数组。

Java 编码解析

import java.util.*;

class Solution {
    public List<String> removeDirectory(String[] paths, String dir) {
        Map<String, List<String>> tree = new HashMap<>();
        List<String> result = new ArrayList<>();

        // 构建目录树
        for (String path : paths) {
            String[] nodes = path.split("/");
            Map<String, List<String>> current = tree;
            for (int i = 1; i < nodes.length; i++) {
                String node = nodes[i];
                current.putIfAbsent(node, new ArrayList<>());
                current = current.get(node);
            }
            // 标记叶子节点
            current.put("", new ArrayList<>());
        }

        // 检查并删除目录
        boolean found = removeFromTree(tree, dir.split("/"), 1);

        // 重建路径数组
        buildPaths(tree, "", result);

        return found && !result.contains(dir + "/") ? result : Arrays.asList(paths);
    }

    private boolean removeFromTree(Map<String, List<String>> tree, String[] dir, int index) {
        if (index == dir.length) {
            // 到达目标目录
            List<String> children = tree.get(dir[index - 1]);
            return children != null && children.isEmpty();
        }

        String key = dir[index];
        List<String> children = tree.get(key);
        if (children == null) {
            return false;
        }

        boolean found = false;
        Iterator<Map.Entry<String, List<String>>> iterator = children.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, List<String>> entry = iterator.next();
            if (removeFromTree(entry.getValue(), dir, index + 1)) {
                found = true;
                if (entry.getValue().isEmpty()) {
                    iterator.remove();
                }
            }
        }

        if (children.isEmpty()) {
            tree.remove(key);
            return true;
        }

        return found;
    }

    private void buildPaths(Map<String, List<String>> tree, String prefix, List<String> result) {
        for (Map.Entry<String, List<String>> entry : tree.entrySet()) {
            String newPrefix = prefix.isEmpty() ? entry.getKey() : prefix + "/" + entry.getKey();
            result.add(newPrefix + "/");
            if (!entry.getValue().isEmpty() && !entry.getValue().containsKey("")) {
                buildPaths(entry.getValue(), newPrefix, result);
            }
        }
    }
}

C++ 编码解析

#include <iostream>
#include <vector>
#include <unordered_map>
#include <string>

using namespace std;

class Solution {
public:
    vector<string> removeDirectory(vector<string>& paths, string dir) {
        unordered_map<string, unordered_map<string, bool>> tree;
        vector<string> result;

        // 构建目录树
        for (const string& path : paths) {
            string current = "/";
            size_t pos = 0;
            while ((pos = path.find("/", pos)) != string::npos) {
                string node = path.substr(0, pos);
                tree[current][node] = false;
                current = node + "/";
                pos++;
            }
            tree[current][""] = true;  // 标记叶子节点
        }

        // 检查并删除目录
        bool found = removeFromTree(tree, dir, 1);

        // 重建路径数组
        buildPaths(tree, "/", result);

        return found && find(result.begin(), result.end(), dir + "/") == result.end() ? result : paths;
    }

private:
    bool removeFromTree(unordered_map<string, unordered_map<string, bool>>& tree, const vector<string>& dir, int index) {
        if (index == dir.size()) {
            auto it = tree.find("/");
            if (it == tree.end()) return false;
            auto childIt = it->second.find(dir[index - 1]);
            return childIt != it->second.end() && childIt->second.empty();
        }

        string key = dir[index];
        auto it = tree.find("/");
        if (it == tree.end() || it->second.find(key) == it->second.end()) {
            return false;
        }

        bool found = false;
        for (auto& pair : it->second[key]) {
            if (removeFromTree(pair.second, dir, index + 1)) {
                found = true;
                if (pair.second.empty()) {
                    it->second.erase(key);
                    break;
                }
            }
        }

        return found;
    }

    void buildPaths(unordered_map<string, unordered_map<string, bool>>& tree, string prefix, vector<string>& result) {
        auto it = tree.find(prefix);
        if (it != tree.end()) {
            result.push_back(prefix);
            for (const auto& pair : it->second) {
                if (!pair.second.empty() || pair.first.empty()) {
                    buildPaths(pair.second, prefix + pair.first, result);
                }
            }
        }
    }
};

Python 编码解析

class Solution:
    def removeDirectory(self, paths: List[str], dir: str) -> List[str]:
        tree = {}
        result = []

        # 构建目录树
        for path in paths:
            nodes = path.split("/")
            current = tree
            for i in range(1, len(nodes)):
                node = nodes[i]
                if node not in current:
                    current[node] = {}
                current = current[node]
            # 标记叶子节点
            current[""] = True

        # 检查并删除目录
        found = self.removeFromTree(tree, dir.split("/"), 1)

        # 重建路径数组
        self.buildPaths(tree, "", result)

        return result if found and dir + "/" not in result else paths

    def removeFromTree(self, tree, dir, index):
        if index == len(dir):
            node = dir[-1]
            children = tree.get(node, {})
            return "" in children and not children.keys() - {""}

        node = dir[index]
        children = tree.get(node, {})
        found = False
        keys_to_remove = []
        for key, sub_tree in children.items():
            if self.removeFromTree(sub_tree, dir, index + 1):
                found = True
                if not sub_tree:
                    keys_to_remove.append(key)

        for key in keys_to_remove:
            del children[key]
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

执着的小火车

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值