leetcode 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
/// 合并
vector<int> nums;
for (auto num : nums1) nums.push_back(num);
for (auto num : nums2) nums.push_back(num);
/// 左边大顶堆,右边小顶堆
priority_queue<int, vector<int>, less<int>> bigHeap;
priority_queue<int, vector<int>, greater<int>> smallHeap;
for (auto num : nums) {
if (bigHeap.empty()) {
bigHeap.push(num);
continue;
}
if (smallHeap.empty()) {
int tmp = bigHeap.top();
bigHeap.pop();
bigHeap.push(min(tmp, num));
smallHeap.push(max(tmp, num));
continue;
}
/// 两个堆一样高时
if (bigHeap.size() == smallHeap.size()) {
if (num >= bigHeap.top()) {
smallHeap.push(num);
} else {
smallHeap.push(bigHeap.top());
bigHeap.pop();
bigHeap.push(num);
}
} /// 大顶堆高
else if (bigHeap.size() > smallHeap.size()) {
if (num >= bigHeap.top()) {
smallHeap.push(num);
} else {
smallHeap.push(bigHeap.top());
bigHeap.pop();
bigHeap.push(num);
}
} /// 小顶堆高
else if (bigHeap.size() < smallHeap.size()) {
if (num <= smallHeap.top()) {
bigHeap.push(num);
} else {
bigHeap.push(smallHeap.top());
smallHeap.pop();
smallHeap.push(num);
}
}
}
if (smallHeap.size() == bigHeap.size()) {
return (smallHeap.top() + bigHeap.top()) / (double)2;
} else if (smallHeap.size() > bigHeap.size()) {
return smallHeap.top();
} else {
return bigHeap.top();
}
}
Leetcode给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转
int reverse(int x) {
int rev=0;
while(x!=0){
if(rev>INT_MAX/10 || rev<INT_MIN/10) return 0;
rev=rev*10+x%10;
x/=10;
}
return rev;
}
Leetcode判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
bool isPalindrome(int x) {
if(x>=0 && x<=9)return true;
if(x%10==0 || x<0)return false;
int rev=0;
while(x>rev){
rev=rev*10+x%10;
x/=10;
}
return rev/10==x || rev==x;
}
Leetcode给定一个只包括 '(',')','{','}','[',']' ===的字符串,判断字符串是否有效。 有效字符串需满足:
1. 左括号必须用相同类型的右括号闭合。
2. 左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
bool isValid(string s) {
if(s.size()%2)return false;
if(s[0]=='}' || s[0]==')' || s[0]==']') return false;
stack<char> sck;
for(int i=0;s[i]!='\0';++i){
if(s[i]=='[' || s[i]=='{' || s[i]=='('){
sck.push(s[i]);
}else{
if(s[i]=='}' && sck.top()!='{') return false;
if(s[i]==']' && sck.top()!='[') return false;
if(s[i]==')' && sck.top()!='(') return false;
sck.pop();
}
}
return sck.empty();
}
class MyQueue {
public:
void push(int x) {
stack1.push(x);
}
int pop() {
if(stack2.empty()){ //只有当stack2为空时,才重新加载
while(!stack1.empty()){ //stack1装填到stack2
stack2.push(stack1.top()); //c++ pop()函数返回值额为void
stack1.pop();
}
}
int res=stack2.top();
stack2.pop();
return res;
}
int peek() {
if(stack2.empty()){
while(!stack1.empty()){
stack2.push(stack1.top());
stack1.pop();
}
}
return stack2.top();
}
bool empty() {
return stack1.empty() && stack2.empty();
}
private:
stack<int> stack1;
stack<int> stack2;
};
push
时间复杂度O(n),而pop
的时间复杂度O(1)class MyStack {
public:
MyStack() {}
void push(int x) {
if(queue1.empty()){
queue1.push(x);
}else{
int cnt=queue1.size();
queue1.push(x);
while(cnt-->0){
queue1.push(queue1.front());
queue1.pop();
}
}
}
int pop() {
int res=queue1.front();
queue1.pop();
return res;
}
int top() {
return queue1.front();
}
bool empty() {
return queue1.empty();
}
private:
queue<int> queue1;
};
push
时间复杂度O(1),而pop
的时间复杂度O(n)private:
queue<int> q1;
void push(int x) {
q1.push(x);
}
int pop() {
queue<int>q2;
while(q1.size()>1){
q2.push(q1.front());
q1.pop();
}
int res=q1.front();
q1=q2;
return res;
}
int top() {
queue<int>q2(q1);
while(q1.size()>1){
q1.pop();
}
int res=q1.front();
q1=q2;
return res;
}
bool empty() {
return q1.empty();
}
};
数据栈
最小栈
最小栈
空间数据栈
pop最小栈
每次都插入当前最小值,出栈时两栈同时popclass MinStack {
public:
void push(int x) {
dataStack.push(x);
if(miniStack.empty()){
miniStack.push(x);
}else{
int min=miniStack.top();
if(min>=x){ //相等时也要插入
miniStack.push(x);
}
}
}
void pop() {
if( dataStack.top()==miniStack.top()){ //只有相等时才同时弹出否则只弹出dataStack
dataStack.pop();
miniStack.pop();
}else{
dataStack.pop();
}
}
int top() {
return dataStack.top();
}
int getMin() {
return miniStack.top();
}
private:
stack<int> dataStack;
stack<int> miniStack;
};
leetcode根据 逆波兰表示法,求表达式的值。 有效的运算符包括 +, -, *, / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。 说明: 整数除法只保留整数部分。 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
输入: ["2", "1", "+", "3", "*"]
输出: 9
解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
stoi()
函数直接将字符串转换为数字,也可以使用ASCII值转,atoi(string.c_str())
int evalRPN(vector<string>& tokens) {
stack<int> sck;
for (auto it : tokens) {
if (it == "+") {
int a = sck.top();
sck.pop();
int b = sck.top();
sck.pop();
sck.push(b + a);
} else if (it == "-") {
int a = sck.top();
sck.pop();
int b = sck.top();
sck.pop();
sck.push(b - a);
} else if (it == "*"){
int a = sck.top();
sck.pop();
int b = sck.top();
sck.pop();
sck.push(a * b);
} else if (it == "/"){
int a = sck.top();
sck.pop();
int b = sck.top();
sck.pop();
sck.push(b / a);
} else {
sck.push(stoi(it));
}
}
return sck.top();
}
leetcode给定一个经过编码的字符串,返回它解码后的字符串。 编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。 此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
输入:s = "3[a]2[bc]"
输出:"aaabcbc"
输入:s = "3[a2[c]]"
输出:"accaccacc"
[
]
匹配得题,首先想到使用栈,既有数字又有字母,想到使用两个栈[ ]
中合成的字符串。 string decodeString(string s) {
string cur = "";
stack<int> numSck;
stack<string> strSck;
int val = 0;
for (int i = 0; s[i] != '\0'; ++i) {
if (s[i] >= '0' && s[i] <= '9') {
val = val * 10 + s[i] - '0';
} else if (s[i] == '[') {
numSck.push(val);
strSck.push(cur);
val = 0;
cur = "";
} else if ((s[i] >= 'a' && s[i] <='z') || (s[i] >= 'A' && s[i] <= 'Z')) {
cur += s[i];
} else if (s[i] == ']') {
int cnt = numSck.top();
numSck.pop();
for (int i = 0; i < cnt; ++i) {
strSck.top() += cur;
}
cur = strSck.top();
strSck.pop();
}
}
return cur;
}
leetcode给你无向 连通 图中一个节点的引用,请你返回该图的 深拷贝(克隆)。
图中的每个节点都包含它的值 val int
和其邻居的列表vector[Node]
。
输入:adjList = [[2,4],[1,3],[2,4],[1,3]]
输出:[[2,4],[1,3],[2,4],[1,3]]
解释:
图中有 4 个节点。
节点 1 的值是 1,它有两个邻居:节点 2 和 4 。
节点 2 的值是 2,它有两个邻居:节点 1 和 3 。
节点 3 的值是 3,它有两个邻居:节点 2 和 4 。
节点 4 的值是 4,它有两个邻居:节点 1 和 3 。
Node* isClone[101];
Node* cloneGraph(Node* node) {
if (node == NULL) return NULL;
if (isClone[node->val] != NULL) return isClone[node->val];
Node* newNode = new Node(node->val);
isClone[node->val] = newNode;
for (auto it : node->neighbors) {
newNode->neighbors.push_back(cloneGraph(it));
}
return newNode;
}
Node* isClone[101];
Node* cloneGraph(Node* node) {
if (!node) return nullptr;
queue<Node*> que;
Node* newNode = new Node(node->val);
isClone[node->val] = newNode;
que.push(node);
while (!que.empty()) {
Node* cur = que.front();
que.pop();
for (Node* e : cur->neighbors) {
if (isClone[e->val] == NULL) {
que.push(e);
isClone[e->val] = new Node(e->val);
}
isClone[cur->val]->neighbors.push_back(isClone[e->val]);
}
}
return newNode;
}
leetcode给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。 岛屿总是被水包围,并且每座岛屿只能由水平方向或竖直方向上相邻的陆地连接形成。 此外,你可以假设该网格的四条边均被水包围。
输入:
[
['1','1','1','1','0'],
['1','1','0','1','0'],
['1','1','0','0','0'],
['0','0','0','0','0']
]
输出: 1
1
时开始深度遍历它的邻接点,凡是dfs遍历途中遇到1
的都改为0,直到所有相连的1全部改为0,这就算找到了一个岛,后面继续遍历改后的二维数组。 int numIslands(vector<vector<char>>& grid) {
int cnt = 0;
for (int i = 0; i < grid.size(); ++i) {
for (int j = 0; j < grid[0].size(); ++j) {
if (grid[i][j] == '1') {
dfs(grid, i, j);
cnt++;
}
}
}
return cnt;
}
void dfs(vector<vector<char> >& grid, int x, int y) {
int row = grid.szie() - 1;
int col = grid[0].szie() - 1;
grid[row][col] = '0';
if (x < row && grid[x + 1][y] == '1') dfs(grid, x + 1, y);
if (x > 0 && grid[x - 1][y] == '1') dfs(grid, x - 1, y);
if (y < col && grid[x][y + 1] == '1') dfs(grid, x, y + 1);
if (y > 0 && grid[x][y - 1] == '1') dfs(grid, x, y - 1);
}
=
写成==
,日啊。第二次犯这种错误了 int numIslands(vector<vector<char>>& grid) {
if (grid.empty()) return 0;
int row = grid.size();
int col = grid[0].size();
int cnt = 0;
queue<pair<int, int> > que;
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
if (grid[i][j] == '1') {
cnt++;
grid[i][j] = '0';
que.push(pair(i, j));
while (!que.empty()) {
pair<int, int> cur = que.front();
que.pop();
int x = cur.first;
int y = cur.second;
if (x - 1 >= 0 && grid[x - 1][y] == '1') {
grid[x - 1][y] = '0';
que.push(pair<int, int>(x - 1, y));
}
if (y - 1 >= 0 && grid[x][y - 1] == '1') {
que.push(pair<int, int>(x, y - 1));
grid[x][y - 1] = '0';
}
if (x + 1 < row && grid[x + 1][y] == '1') {
que.push(pair<int, int>(x + 1, y));
grid[x + 1][y] = '0';
}
if (x + 1 < row && grid[x + 1][y] == '1') {
que.push(pair<int, int>(x + 1, y));
grid[x + 1][y] = '0';
}
if (y + 1 < col && grid[x][y + 1] == '1') {
que.push(pair<int, int>(x, y + 1));
grid[x][y + 1] = '0';
}
}
}
}
}
return cnt;
}
leetcode给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。
dd 以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。
int largestRectangleArea(vector<int>& heights) {
if (heights.empty()) return 0;
int res = INT_MIN;
for (int i = 0; i < heights.size(); ++i) {
int left = i, right = i;
while (left > 0 && heights[left - 1] >= heights[i]) left--;
while (right < heights.size() - 1 && heights[right + 1] >= heights[i]) right++;
int len = right - left + 1;
res = max(res, heights[i] * len);
}
return res;
}
leetcode 给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。 两个相邻元素间的距离为 1 。
0 0 0
0 1 0
1 1 1
输出:
0 0 0
0 1 0
1 2 1
int off[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
int row = matrix.size();
int col = matrix[0].size();
// 初始化
bool isVis[row][col];
for (int i = 0; i < row; ++i) {
memset(isVis[i], 0, col);
}
// 入队列的顺序:所有0的位置,所有离0点距离为1的点,所有离0点距离为2的点....
queue<pair<int, int>> que;
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
if (matrix[i][j] == 0) {
que.push({i, j});
isVis[i][j] = true;
}
}
}
while (!que.empty()) {
int x = que.front().first;
int y = que.front().second;
que.pop();
for (int i = 0; i < 4; ++i) {
int xi = x + off[i][0];
int yi = y + off[i][1];
if (xi >= 0 && xi < row && yi >= 0 && yi < col && !isVis[xi][yi]) {
isVis[xi][yi] = true;
matrix[xi][yi] = matrix[x][y] + 1;
que.push({xi, yi});
}
}
}
return matrix;
}
leetcode设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。 你的实现应该支持如下操作:
MyCircularQueue(k): 构造器,设置队列长度为 k 。
Front: 从队首获取元素。如果队列为空,返回 -1 。
Rear: 获取队尾元素。如果队列为空,返回 -1 。
enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
isEmpty(): 检查循环队列是否为空。
isFull(): 检查循环队列是否已满。
head
和tail
,注意满队和空队的条件,满队时:tail
就在head
的前一格,空队时:tail
和head
都指向-1。size
取模才能保证不超过size
大小。class MyCircularQueue {
private:
vector<int> data;
int size;
int head;
int tail;
public:
MyCircularQueue(int k) {
data.resize(k);
size = k;
head = -1;
tail = -1;
}
bool enQueue(int value) {
if (isFull()) return false;
if (isEmpty()) head = 0;
tail = (tail + 1) % size;
data[tail] = value;
return true;
}
bool deQueue() {
if (isEmpty()) return false;
if (head == tail) { // 只剩一个元素时
head = -1;
tail = -1;
return true;
}
head = (head + 1) % size;
return true;
}
int Front() {
if (isEmpty()) return -1;
return data[head];
}
int Rear() {
if (isEmpty()) return -1;
return data[tail];
}
bool isEmpty() {
return head == -1;
}
bool isFull() {
return (tail + 1) % size == head;
}
};
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。