立志重刷代码随想录60天冲冲冲!!——第二十六天

106.从中序与后序遍历序列构造二叉树

补更,二叉树构造!!这个非常重要!!

分六部分:

// 1、后序数组为空,返回空节点

// 2、后序数组最后一个元素,为节点元素。数组大小为1,返回节点。

// 3、以上一节点元素作为切割点,寻找中序数组的位置

// 4、切割中序数组

// 5、切割后序数组

// 6、递归处理左右区间

class Solution {
public:
    // 1、后序数组为空,返回空节点
    // 2、后序数组最后一个元素,为节点元素
    // 3、以上一节点元素作为切割点,寻找中序数组的位置
    // 4、切割中序数组
    // 5、切割后序数组
    // 6、递归处理左右区间 
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if (postorder.size() == 0) return NULL; // 终止条件
        int postValue = postorder.back();   // 后序最后一个元素
        TreeNode* node = new TreeNode(postValue); 
        if (postorder.size() == 1) return node; // 如果后序数组就剩一个元素,返回刚刚创建的节点
        
        int postIdx = 0;
        for (int i = 0; i < inorder.size(); i++) {
            if (inorder[i] == postValue) {
                postIdx = i;
                break;
            }
        }

        // 切割中序 (左闭右开)
        vector<int> Leftinorder(inorder.begin(), inorder.begin() + postIdx);
        vector<int> Rightinorder(inorder.begin() + postIdx + 1, inorder.end());
        // 切割后序 (左闭右开)
        vector<int> Leftpostorder(postorder.begin(), postorder.begin() + postIdx);
        vector<int> Rightpostorder(postorder.begin() + postIdx, postorder.end() - 1);

        node->left = buildTree(Leftinorder, Leftpostorder);
        node->right = buildTree(Rightinorder, Rightpostorder);

        return node;
    }
};

46.全排列

class Solution {
public:
    vector<vector<int>> res;
    vector<int> path;
    void backtracking(vector<int>& nums, vector<bool>& used) {
        // 终止条件
        if (path.size() == nums.size()) {
            res.push_back(path);
            return;
        }

        for (int i = 0; i < nums.size(); i++) {
            if (used[i] == true) continue;

            path.push_back(nums[i]);
            used[i] = true;
            backtracking(nums, used);
            used[i] = false;
            path.pop_back();
        }
        return;
    }

    vector<vector<int>> permute(vector<int>& nums) {
        vector<bool> used(nums.size(), false);
        backtracking(nums, used);
        return res;
    }
};

47.全排列 II

多判断一个 同一层循环相邻重复元素的去重

class Solution {
public:
    vector<vector<int>> res;
    vector<int> path;
    void backtracking(vector<int>& nums, vector<bool>& used) {
        if (path.size() == nums.size()) {
            res.push_back(path);
            return;
        }

        for (int i = 0; i < nums.size(); i++) {
            if (used[i] == true) continue; // 全排列,同位置跳过
            if ((i > 0 && nums[i-1] == nums[i] && used[i-1] == true)) continue; // 去重
            path.push_back(nums[i]);
            used[i] = true;
            backtracking(nums, used);
            used[i] = false;
            path.pop_back();
        }
        return;
    }

    vector<vector<int>> permuteUnique(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        vector<bool> used(nums.size(), false);
        backtracking(nums, used);
        return res;
    }
};

代码随想录更新 文章被收录于专栏

冲冲冲冲冲冲!

全部评论

相关推荐

嵌入式系统作为当前最热门且最有发展前途的IT应用领域之一,吸引了大量有志于从事该行业的学习者。为了系统地掌握嵌入式开发技能,以下是一条详细的学习路线,旨在帮助初学者逐步成长为专业的嵌入式开发工程师。一、基础学习阶段1.&nbsp;Linux基础目标:掌握Linux的基本操作、基本服务配置及设计理念。学习内容:Linux系统安装与配置(推荐使用Ubuntu系统)。Shell编程基础,包括文件操作、用户管理、进程控制等。推荐书籍:《鸟哥的Linux私房菜-基础学习篇》。推荐视频:Linux学习建议、系统结构与终端控制台、文件相关命令等。2.&nbsp;C语言基础目标:精通C语言,特别是指针、内存管理、模块化编译等。学习内容:C语言基础语法、数据类型、控制结构、函数等。指针与数组、结构体、链表等数据结构。内存分配与管理、gcc、Makefile、GDB等工具使用。推荐书籍:《C程序设计语言》、《C语言核心技术》、《C和指针》。推荐视频:C语言入门系列、C语言提高篇等。二、进阶学习阶段1.&nbsp;Unix环境高级编程目标:深入理解Unix/Linux环境下的进程、线程、网络编程等。学习内容:进程、线程管理。文件I/O、文件锁、管道、消息队列等。Socket网络编程、TCP/IP协议。推荐书籍:《UNIX环境高级编程》、《TCP/IP详解》。推荐视频:UNIX网络开发系列。2.&nbsp;嵌入式汇编与体系结构目标:掌握ARM体系结构及嵌入式汇编语言。学习内容:ARM处理器基础、指令集。嵌入式汇编语言编程。ARM开发板使用与电路原理图理解。推荐书籍:《ARM嵌入式系统开发—软件设计与优化》、《嵌入式Linux应用开发完全手册》。推荐视频:嵌入式开发入门经典教程系列、ARM体系结构与Bootloader开发等。三、嵌入式开发实践1.&nbsp;嵌入式应用开发目标:能够基于ARM平台开发简单的嵌入式应用程序。学习内容:嵌入式Linux系统移植与配置。编写简单的嵌入式应用程序,如串口通信、LED控制等。实战案例:串口监听程序、图片浏览器、MP3播放器等。2.&nbsp;Linux内核与驱动开发目标:掌握Linux内核与驱动开发,成为嵌入式内核驱动级别的开发者。学习内容:Linux内核架构与工作原理。Linux设备驱动开发,包括字符设备、块设备、网络设备等。实战案例:GPIO驱动、RTC时钟驱动、LCD显示设备驱动等。推荐书籍:《深入理解Linux内核》、《Linux设备驱动程序》、《Linux内核设计与实现》。四、持续学习与提升持续跟踪新技术:嵌入式技术日新月异,需要不断学习新技术、新工具。参与项目实践:通过参与实际项目,提升解决问题的能力和团队协作能力。深入内核源码:阅读Linux内核源码,深入理解其设计思想和实现方式。通过以上学习路线,你将能够系统地掌握嵌入式开发所需的知识和技能,逐步成长为一名专业的嵌入式开发工程师。#嵌入式学习规划##25届校招[话题]##嵌入式介绍##嵌入式学习规划#
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务