
大家好,我是小卡皮巴拉
文章目录
目录
[兄弟们共勉 !!!](#兄弟们共勉 !!!)
每篇前言
博客主页:小卡皮巴拉
咱的口号:🌹小比特,大梦想🌹
作者请求:由于博主水平有限,难免会有错误和不准之处,我也非常渴望知道这些错误,恳请大佬们批评斧正。
**笔试强训题目:**两个数组的交集
原题链接:两个数组的交集_牛客题霸_牛客网
题目描述
给定两个整数数组分别为nums1nums1, nums2nums2,找到它们的公共元素并按返回。
数据范围:
1≤nums1.length,nums2.length≤10001≤nums1.length,nums2.length≤1000
1≤nums1[i],nums2[i]≤10001≤nums1[i],nums2[i]≤1000
示例1
输入:[1,2],[2,2,2,2]
返回值:[2]
说明:两个数组的公共元素只有2
示例2
输入:[1,2,3],[8,2,2,3,8]
返回值:[2,3]
说明:两个数组的公共元素为2和3,返回[3,2]也是一个正确的答案
解题思路
问题理解
本题给定两个整数数组 nums1 和 nums2,要求找出它们的公共元素并返回。公共元素指的是在两个数组中都出现过的元素,且返回结果中每个公共元素只需出现一次,不考虑其在原数组中的出现次数。
算法选择
**采用哈希表(Hash Table)的方法。**哈希表具有 O (1) 的平均查找时间复杂度,能够高效地标记和检查元素是否存在,同时可以通过标记状态的改变确保结果中每个元素只出现一次,整体时间复杂度为 O (n + m)(n 和 m 分别为两个数组的长度)。
具体思路
-
初始化:定义一个大小为 1010 的哈希数组 hash(因元素范围为 1~1000),并初始化为 false,用于标记第一个数组中的元素。
-
标记第一个数组元素:遍历数组 nums1,对于每个元素 x,将哈希数组中对应位置 hash [x] 设为 true,以此记录 nums1 中出现的所有元素。
-
查找并收集公共元素:遍历数组 nums2,对于每个元素 x,检查哈希数组中 hash [x] 是否为 true:
-
若为 true,说明 x 是两个数组的公共元素,将其添加到结果数组 ret 中
-
同时将 hash [x] 设为 false,防止后续再次添加该元素(确保结果中无重复)
-
-
返回结果:遍历结束后,结果数组 ret 中存储的就是两个数组的所有公共元素,返回 ret 即可。
解题要点
-
哈希数组的大小:根据题目中元素的范围(1≤元素≤1000),选择大小为 1010 的数组作为哈希表,既节省空间又能覆盖所有可能的元素。
-
去重处理:通过将已找到的公共元素在哈希表中标记为 false,确保每个公共元素在结果中只出现一次,满足题目要求。
-
遍历顺序:先遍历第一个数组标记元素,再遍历第二个数组查找公共元素。
-
无需考虑顺序:题目允许返回结果中元素的顺序任意,因此无需对结果数组进行排序操作,简化了实现过程。
完整代码(C++)
cpp
#include <vector>
class Solution {
public:
bool hash[1010] = { 0 };
vector<int> intersection(vector<int>& nums1, vector<int>& nums2)
{
vector<int> ret;
for(auto x : nums1)
{
hash[x] = true;
}
for(auto x : nums2)
{
if(hash[x])
{
ret.push_back(x);
hash[x] = false;
}
}
return ret;
}
};
**笔试强训题目:**点击消除
原题链接:点击消除_牛客题霸_牛客网
题目描述
牛牛拿到了一个字符串。
他每次"点击",可以把字符串中相邻两个相同字母消除,例如,字符串"abbc"点击后可以生成"ac"。
但相同而不相邻、不相同的相邻字母都是不可以被消除的。
牛牛想把字符串变得尽可能短。他想知道,当他点击了足够多次之后,字符串的最终形态是什么?
输入描述:
一个字符串,仅由小写字母组成。(字符串长度不大于300000)
输出描述:
一个字符串,为"点击消除"后的最终形态。若最终的字符串为空串,则输出0。
示例1
输入:abbc
输出:ac
示例2
输入:abba
输出:0
示例3
输入:bbbbb
输出:b
示例4
输入:abbba
输出:aba
解题思路
问题理解
本题要求对一个仅由小写字母组成的字符串进行 "点击消除" 操作:每次可以消除相邻的两个相同字母,直到无法再消除为止,最终返回最短的字符串形态。若最终字符串为空,则输出 "0"。
算法选择
采用栈(Stack)的数据结构来解决。栈的特性是 "后进先出",非常适合处理这种需要不断检查和消除相邻元素的场景,能够高效地模拟连续消除的过程,整体时间复杂度为 O (n)(n 为字符串长度),空间复杂度为 O (n)。
具体思路
-
初始化 :定义一个空字符串
st
作为栈,用于存储处理过程中的字符。 -
遍历输入字符串 :对于字符串中的每个字符
x
:-
检查栈是否不为空,且栈顶元素(即
st
的最后一个字符)与当前字符x
相同。 -
若满足上述条件,说明出现相邻相同字符,执行消除操作:将栈顶元素弹出(
st.pop_back()
)。 -
若不满足条件,将当前字符
x
压入栈中(st += x
)。
-
-
处理结果:遍历结束后,检查栈的长度:
-
若栈为空,输出 "0"。
-
若栈不为空,输出栈中的字符串。
-
解题要点
-
栈的使用 :利用字符串模拟栈的操作,通过
back()
方法访问栈顶元素,pop_back()
方法弹出栈顶元素,+=
操作压入元素,简洁高效。 -
连续消除的处理:栈的结构确保了每次添加新字符时,都会与前一个字符(栈顶)进行比较,若相同则立即消除,这种方式能自动处理多次连续消除的情况(如 "bbbbb" 会被逐步消除为 "b")。
-
边界情况处理:当最终栈为空时,需按照题目要求输出 "0",而非空字符串。
完整代码(C++)
cpp
#include <iostream>
using namespace std;
int main()
{
string s,st;
cin >> s;
for(auto x : s)
{
if(st.size() && st.back() == x)
st.pop_back();
else
st += x;
}
cout << (st.size() == 0 ? "0" : st) << endl;
return 0;
}
兄弟们共勉 !!!
码字不易,求个三连
抱拳了兄弟们!
