左神算法与数据结构——中级提升班-2

文章提供了多个编程挑战,包括数组中差值为k的去重数字对、调整集合元素以保持平均值增长的魔法操作、计算括号序列的深度、排序栈以及数字到字母字符串的转换问题。这些问题涉及到数据结构、算法和逻辑思维,是常见的面试题类型。
摘要由CSDN通过智能技术生成

中级提升班-2

题目一返回arr去重数字对

给定一个数组arr,求差值为k的去重数字对。

比较简单,上代码

vector<vector<int>> process1(vector<int> nums, int val) {
    vector<vector<int>> res;
    if (nums.size() < 1) {
        return res;
    }
    unordered_map<int, int> umap;
    for (int i = 0; i < nums.size(); i++) {
        for (int j = 0; j < i; j++) {
            if (nums[i] - nums[j] == val && umap.find(nums[i]) == umap.end()) {
                umap.insert({ nums[i], nums[j] });
                res.push_back({ nums[i], nums[j] });
            }
        }
        for (int j = i + 1; j < nums.size(); j++) {
            if (nums[i] - nums[j] == val && umap.find(nums[i]) == umap.end()) {
                umap.insert({ nums[i], nums[j] });
                res.push_back({ nums[i], nums[j] });
            }
        }
    }
    return res;
}
int findPairs(vector<int>& nums, int k) {
    unordered_set<int> visited;
    unordered_set<int> res;
    for (int num : nums) {
        if (visited.count(num - k)) {
            res.emplace(num - k);
        }
        if (visited.count(num + k)) {
            res.emplace(num);
        }
        visited.emplace(num);
    }
    return res.size();
}

笔试面试考题区别

在这里插入图片描述

题目二magic操作

给一个包含n个整数元素的集合a,一个包含m个整数元素的集合b。
定义magic操作为,从一个集合中取出一个元素,放到另一个集合里,且操作过
后每个集合的平均值都大大于于操作前。
注意以下两点:
1)不可以把一个集合的元素取空,这样就没有平均值了
2)值为x的元素从集合b取出放入集合a,但集合a中已经有值为x的元素,则a的
平均值不变(因为集合元素不会重复),b的平均值可能会改变(因为x被取出
了)
问最多可以进行多少次magic操作?

  • 经分析,只能将大平均值放到小平均值中,范围为大平均和小平均之间的数字,从最小的数字中开始提取
double average(vector<int> a) {
    int sum = 0;
    for (int num : a) {
        sum += num;
    }
    double res = (double)sum / a.size();
    return res;
}

int magicOpts(vector<int> a, vector<int> b) {
    double avea = average(a);
    double aveb = average(b);
    if (avea == aveb) {
        return 0;
    }
    vector<int> big;
    vector<int> small;
    double avebig = 0;
    double avesmall = 0;
    if (avea > aveb) {
        avebig = avea;
        avesmall = aveb;
        big = a;
        small = b;
    }
    else {
        avebig = aveb;
        avesmall = avea;
        big = b;
        small = a;
    }
    sort(big.begin(), big.end());
    unordered_set<int> uset;
    for (int num : small) {
        uset.insert(num);
    }
    int ops = 0;
    for (int i = 0; i < big.size(); i++) {
        if (big[i] > average(small) && big[i] < average(big) && !uset.count(big[i])) {
            uset.insert(big[i]);
            small.push_back(big[i]);
            big.erase(big.begin() + i);
            ops++;
        }
    }
    cout << ops << endl;
    return ops;
}

题目四括号深度问题,最大长度

一个合法的括号匹配序列有以下定义:
①空串"“是一个合法的括号匹配序列
②如果"X"和"Y"都是合法的括号匹配序列,“XY"也是一个合法的括号匹配序列
③如果"X"是一个合法的括号匹配序列,那么”(X)“也是一个合法的括号匹配序列
④每个合法的括号序列都可以由以上规则生成。
例如: “”,”()”,“()()”,"((()))“都是合法的括号序列
对于一个合法的括号序列我们又有以下定义它的深度:
①空串”“的深度是0
②如果字符串"X"的深度是x,字符串"Y"的深度是y,那么字符串"XY"的深度为
max(x,y) 3、如果"X"的深度是x,那么字符串”(X)"的深度是x+1
例如: "()()()“的深度是1,”((()))"的深度是3。牛牛现在给你一个合法的括号
序列,需要你计算出其深度。

  • 遇到( count++,)count–
int parenthesesDeep(string str) {
    int res = 0;
    int count = 0;
    for (int i = 0; i < str.length(); i++) {
        if (str[i] == '(') {
            count++;
        }
        else {
            count--;
        }
        res = max(res, count);
    }
    cout << res << endl;
    return res;
}

必须连续的子串或者子数组,求每个位置结尾的情况下, 答案是多少

题2:

在这里插入图片描述

思路:

  • 题目所求为最长连续字串,应当想到在每个位置结尾情况下的dp数组
    1. 如果 i 来到为(,则为0
    2. 如果 i 来到为),i - 1表示该位为结尾最长括号为k,则需要看i - 1 - k位上是否位(,若不是,则填0,如果是(,需要再加上i - 1 - k - 1位上的值。

在这里插入图片描述

返回有序栈

题目:

请编写一个程序,对一个栈里的整型数据,按升序进行排序(即排序前,栈里
的数据是无序的,排序后最大元素位于栈顶),要求最多只能使用一个额外的
栈存放临时数据,但不得将元素复制到别的数据结构中

stack<int> maxStack(stack<int>& st) {
    stack<int> st2;
    while (!st.empty()) {
        int top = st.top();
        st.pop();
        if (st2.empty() || top < st2.top()) {
            st2.push(top);
        }
        else {
            while (!st2.empty() && top > st2.top()) {
                st.push(st2.top());
                st2.pop();
            }
            st2.push(top);
        }
    }
    while (!st2.empty()) {
        st.push(st2.top());
        st2.pop();
    }
    return st;
}

题目三转换字符串个数

题目

将给定的数转换为字符串,原则如下:1对应 a,2对应b,……26对应z,例如12258
可以转换为"abbeh", “aveh”, “abyh”, “lbeh” and “lyh”,个数为5,编写一个函
数,给出可以转换的不同字符串的个数

老熟人了

int process1(int i, string str) {
    if (i == str.length()) {
        return 1;
    }
    if (str[i] == '0') {
        return 0;
    }
    int res = process1(i + 1, str);
    if (i == str.length() - 1) {
        return res;
    }
    if (((str[i] - '0') * 10 + (str[i + 1] - '0')) < 27) {
        res += process1(i + 2, str);
    }
    return res;
}

int processDP(string str) {
    if (str.length() < 1) {
        return 0;
    }
    vector<int> dp(str.length() + 1);
    dp[str.length()] = str[str.length() - 1] == '0' ? 0 : 1;
    for (int i = str.length() - 1; i >= 0; i--) {
        if (str[i] == '0') {
            dp[i] = 0;
        }
        else {
            int res = dp[i + 1];
            if (i + 2 < dp.size() && ((str[i] - '0') * 10 + (str[i + 1] - '0')) < 27) {
                res += dp[i + 2];
            }
            dp[i] = res;
        }
    }
    return dp[0];
}

二叉树最大权值

二叉树每个结点都有一个int型权值,给定一棵二叉树,要求计算出从根结点到
叶结点的所有路径中,权值和最大的值为多少。

int process1(Node* head) {
    if (head->left == nullptr && head->right == nullptr) {
        return head->val;
    }
    int res = 0;
    if (head->left != nullptr) {
        res = process1(head->left);
    }
    if (head->right != nullptr) {
        res = max(process1(head->right), res);
    }
    return res + head->val;
}

已经秒杀惹

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值