AcWing 35. 反转链表 (3月18日)
注意
if (!head || !head->next) return head;
表示只有一个点
一定要加!head->next 否则递归死
分析
迭代的话, 只需要挨个翻转即可
注意head->next = NULL 因为头节点变成了尾节点, 因此需要置空
code
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (!head || !head->next) return head; // 一定要加!head->next 特判一个点
auto a = head, b = head->next;
while (b){
auto c = b->next;
b->next = a;
a = b, b = c;
}
head->next = NULL;
return a;
}
};
code(递归)
递归完后变成这样
需要做的操作
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (!head || !head->next ) return head; // 一定要+ !head->next 特判一个点
auto tail = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return tail;
}
};
LeetCode 92. 反转链表 II
见leetcode究极班
1603. 设计停车系统(3月19日)
分析
每个车场停车位数有限制, 进来一个, 位数就少1个
根据车的类型分到3个场地
如果分的时候, 发现某个场地满了, return false;
停车场的话, 只会用到停车的位数
开个长度为3的车场的剩余位数
code
class ParkingSystem {
public:
vector<int> tot;
ParkingSystem(int big, int medium, int small) {
tot = {big, medium, small};
}
bool addCar(int carType) {
carType = carType - 1; // 题目cartype从1开始, 所以要-1
if (tot[carType] >= 1){
tot[carType] --;
return true;
}
return false;
}
};
/**
* Your ParkingSystem object will be instantiated and called as such:
* ParkingSystem* obj = new ParkingSystem(big, medium, small);
* bool param_1 = obj->addCar(carType);
*/
3267. 小明上学
分析
路上的时间, 直接累加就可以了
红绿灯的时间, 需要手算一下, 还需要等多久
红灯的话, 返回剩余时间t即可, 因为红灯要等
绿灯直接0, 通行
黄灯的话, 也要等t, 再等红灯r, 所以是t + r
code
#include <iostream>
using namespace std;
int main(){
int r, y, g;
cin >> r >> y >> g;
int n;
cin >> n;
int res = 0;
while (n -- ){
int k, t;
scanf("%d%d", &k, &t);
if (!k) res += t; // 路
else if (k == 1) res += t; // 红灯
else if (k == 2) res += t + r; // 黄灯
}
cout << res << endl;
return 0;
}
150. 逆波兰表达式求值
见leetcode究极班
分析
code
3302. 表达式求值
分析
中缀表达式, 表达式树中, 从当前点往上走, 表示当前点往上走的父节点 运算符优先级 低于 当前点,
如果当前点的父亲节点运算符比当前点运算符优先级低, 表示往上走了.
如图, + 比x优先级要低, 表示往上走了, 也表示当前x的子树已经遍历完了
如果运算符优先级相同, 也是要往上走
以上是不考虑括号的情况
遇到右括号的话, 因为中缀表达式, 在表达式树上是从上往下运算符递增的,因此括号内的运算符需要从右往左算, 即:直接从栈里弹出计算
code
#include <iostream>
#include <cstring>
#include <stack>
#include <unordered_map>
using namespace std;
stack<int> num;
stack<char> op;
void eval(){
auto b = num.top(); num.pop();
auto a = num.top(); num.pop();
auto c = op.top(); op.pop();
int x;
if (c == '+') x = a + b;
else if (c == '-') x = a - b;
else if (c == '*') x = a * b;
else x = a / b;
num.push(x);
}
int main(){
unordered_map<char, int> pr{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};
string str;
cin >> str;
for (int i = 0; i < str.size(); i ++ ){
auto c = str[i];
if (isdigit(c)){
int x = 0, j = i;
while (j < str.size() && isdigit(str[j]))
x = x * 10 + str[j ++ ] - '0';
i = j - 1;
num.push(x);
}
else if (c == '(') op.push(c);
else if (c == ')'){
while (op.top() != '(') eval();
op.pop();
}else {
while (op.size() && pr[op.top()] >= pr[c]) eval();// pr[op.top()]表示父亲节点运算符优先级
op.push(c);
}
}
while (op.size()) eval();
cout << num.top() << endl;
return 0;
}