嵌入式面试准备

孤儿进程

父进程先于子进程结束,也就意味着,此时子进程变成了一个孤儿进程,在Linux系统中,所有孤儿进程都自动变成init进程的子进程。

也就是说,某一子进程的父进程结束后,该子进程调用getppid()将会返回1。

但是在图形界面下的一个后台守护进程,会成为孤儿进程的父进程。

长度最小的子数组

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int left = 0, right = 0, n = nums.size();
        int ret = INT_MAX;
        int sum = nums[left];
        while(left <= right && right < n){
            if(sum >= target){
                ret = min(ret, right-left+1);
                sum -= nums[left];
                left++;
            }else{
                right++;
                if(right < n){
                    sum += nums[right];
                }
            }
        }
        
        return ret == INT_MAX ? 0: ret;
    }
};

路径总和

在这里插入图片描述

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool dfs(TreeNode* root, int targetSum, int sum){
        if(root == nullptr){
            return false;
        }
        if(root->left == nullptr && root->right == nullptr){
            sum += root->val;
            return sum == targetSum;
        }
        return dfs(root->left, targetSum, sum+root->val) || dfs(root->right, targetSum, sum+root->val);
    }
    bool hasPathSum(TreeNode* root, int targetSum) {
        return dfs(root, targetSum, 0);
    }
};

完全二叉树的节点个数

给一棵完全二叉树的根节点root,求出该树的节点个数。

在这里插入图片描述
对于任意二叉树,都可以通过深度优先搜索或广度优先搜索计算节点的个数,时间复杂度和空间复杂度都是O(N)。

根节点位于第0层,最大层数为h。

守护进程

守护进程(daemon),是运行在后台的一种特殊进程,它独立于控制终端,并且周期性地执行某种任务或等待处理某些事情的发生,主要表现为两个特点:

  1. 长期运行。守护进程是一种生存期很长的一种进程,它们一般在系统启动时开始运行,除非强行终止,否则直到系统关机之前都会保持运行。与守护进程相比,普通进程都是在用户登录或执行程序时创建,在运行结束或用户注销时终止,但守护进程不受用户登录注销的影响,它们将会一只运行着,直到系统关机。
  2. 与控制终端脱离。普通进程都是和控制终端想绑定的,会受到终端的控制、影响;但守护进程它脱离了控制终端,目的就是为了不受到控制终端的控制、影响,同时守护进程也不会将运行过程的信息通过终端显示出来,更不会通过终端与用户进行交互。

Linux系统中有很多种系统服务,大多数服务都是通过守护进程实现的,譬如系统日志服务syslog,web服务httpd,邮件服务sendmail和数据库服务mysqld等。守护进程名字通常以d结尾。

如何编写守护进程

守护进程的重点在于脱离控制终端。

  1. 创建子进程,终止父进程。

  2. 子进程调用setsid创建新的会话。

  3. 将当前工作目录更改为根目录。

  4. 重新设置文件权限掩码umask。

  5. 关闭打开的文件描述符

  6. 忽略SIGCHLD信号。

将有序数组转换为二叉搜索树

在这里插入图片描述

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* helper(vector<int>& nums, int left, int right) {
        if (left == right) {
            return new TreeNode(nums[left]);
        }
        if (left < right) {
            int mid = (left + right) / 2;
            TreeNode* root = new TreeNode(nums[mid]);
            root->left = helper(nums, left, mid - 1);
            root->right = helper(nums, mid + 1, right);
            return root;
        }
        return nullptr;
    }
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        int n = nums.size();
        if (n == 1) {
            return new TreeNode(nums[0]);
        }
        int mid = n / 2;
        TreeNode* root = new TreeNode(nums[mid]);
        root->left = helper(nums, 0, mid - 1);
        root->right = helper(nums, mid + 1, n - 1);
        return root;
    }
};

搜索插入位置

在这里插入图片描述
假如是在排序数组中寻找一个目标值,那么直接利用二分法就可以在O(log n)找到目标值,但是这题添加了额外条件,如果不存在数组中的时候,需要返回插入顺序。

插入位置。

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        //找到第一个大于等于target的元素,其下标就是返回值
        //如果一直找不到,意味着所有元素都小于target,直接放到末尾。
        int left = 0, right = nums.size()-1, ret = nums.size();

        while(left <= right){
            int mid = left + ((right-left) >> 1);
            if(nums[mid] >= target){
                ret = mid;
                right = mid - 1;
            }else{
                left = mid + 1;
            }
        }
        return ret;
    }
};

搜索二维矩阵

矩阵满足:

  • 每行从左到右非严格递增
  • 没好第一个整数大于前一行最后一个整数。

给一个整数target,如果target在矩阵中,返回true,否则返回false。

在这里插入图片描述
两次二分查找
由于每行的第一个元素大于前一行的最后一个元素,所以每行第一个元素一定大于前一行顶一个元素,所以第一列是升序的。

可以对矩阵的第一列的元素二分查找,找到最后一个小于等于target目标值的元素,然后在该元素所在行中二分查找目标值。

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int m = matrix.size(), n = matrix[0].size();
        int i = 0, j = 0;
        int index = -1;
        for(i=0; i<m; i++){
            if(matrix[i][0] <= target){
                index = i;
            }
        }
        if(index == -1){
            return false;
        }

        for(j=0; j<n; j++){
            if(matrix[index][j] == target){
                return true;
            }
        }
        return false;
    }
};

跳跃游戏二

在这里插入图片描述

贪心地进行正向查找,每次找到可到达的最远的位置,就可以在线性时间内得到最少跳跃次数。

维护能够到达的最大下标位置,记为边界。到达边界时,更新边界,并把跳跃次数加1。

class Solution {
public:
    int jump(vector<int>& nums) {
        int maxPos = 0, end = 0, n = nums.size(), step = 0;
        for (int i = 0; i < n - 1; i++) {
            if (maxPos >= i) { //i处可达
                maxPos = max(maxPos, i + nums[i]);
                if (i == end) {
                    end = maxPos;
                    step++;
                }
            }
        }
        return step;
    }
};

完全二叉树的节点个数

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool checkNode(TreeNode* root, int level, int index){
        for(int i=level-2; i>=0 && root!=nullptr; i--){
            if((index >> i) & 1){
                root = root->right;
            }else{
                root = root->left;
            }
        }
        return root != nullptr;
    }
    int countNodes(TreeNode* root) {
        int level = 0;
        TreeNode* p = root;
        while(p){
            level++;
            p = p->left;
        }
        if(level == 0 || level == 1){
            return level;
        }
        int left = 1 << (level - 1);
        int right = (1 << level) - 1;

        int ret = 0;
        while(left <= right){
            int mid = left + ((right - left) >> 1);
            if(checkNode(root, level, mid)){
                ret = mid;
                left = mid + 1;
            }else{
                right = mid - 1;
            }
        }
        return ret;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

饼干饼干圆又圆

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

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

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

打赏作者

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

抵扣说明:

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

余额充值