lc84.单调栈
class Solution {
public:
int largestRectangleArea(vector<int>& heights) {
stack<int> st;
heights.insert(heights.begin(), 0);
heights.push_back(0);
st.push(0);
int result = 0;
for (int i = 1; i < heights.size(); i++)
{
while (heights[i] < heights[st.top()])
{
int mid = st.top();
st.pop();
int w = i - st.top() - 1;
int h = heights[mid];
result = max(result, w * h);
}
st.push(i);
}
return result;
}
};
lc41
原地hash,换位置标识
nums[nums[i] - 1] != nums[i])
swap(nums[i], nums[nums[i] - 1]);
类似:7.11刷到的lc442
原地hash,nums[i]位置元素*-1找出现两次的
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int n = nums.size();
for (int i = 0; i < n; ++i) {
// 保证交换的索引在有效范围内,且是正数
while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) {
swap(nums[i], nums[nums[i] - 1]);
}
}
for (int i = 0; i < n; ++i) {
if (nums[i] != i + 1) {
return i + 1;
}
}
return n + 1;
}
};
lc23.堆
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists)
{
auto cmp = [](const ListNode* a, const ListNode* b)
{
return a->val > b->val; // 最小堆
};
priority_queue<ListNode*, vector<ListNode*>, decltype(cmp)> pq;
for (auto head : lists)
{
if (head)
{
pq.push(head); // 非空链表头结点入堆
}
}
ListNode dummy{}; // 哨兵节点
auto cur = &dummy;
while (!pq.empty())
{
auto node = pq.top();
pq.pop();
if (node->next)
{
pq.push(node->next);
}
cur->next = node;
// 把 node 添加到新链表的末尾
cur = cur->next;
}
return dummy.next;
}
};
lc2529. 闭区间二分
class Solution {
public:
int maximumCount(vector<int>& nums)
{
int n=nums.size();
return max(lowerbound(nums, 0),n- lowerbound(nums, 1));
}
//闭区间写法,第一个大于等于target的索引
int lowerbound(vector<int>& nums,int target)
{
int left = 0, right = nums.size() - 1;
while(left <= right)
{
int mid = (left + right) / 2;
if(nums[mid] < target)
left = mid + 1;
else
right = mid - 1;
}
return left;
}
};
一等公民:自由的赋值
cpp实现:function
在编程里,“一等公民(first - class citizen )”指一种程序实体,可像其他普通值一样,自由地赋值给变量、作为参数传递给函数、从函数返回 。
C++ 示例(函数作为一等公民相关,C++ 中函数本身不是严格一等公民,但可通过函数对象、 std::function 等模拟 )
#include <iostream>
#include <functional>
// 普通函数
int add(int a, int b) { return a + b; }
int main() {
// 函数指针存储函数,函数可赋值给变量
std::function<int(int, int)> func = add;
// 函数作为参数传递给另一个函数(这里直接调用演示,也可传给其他函数 )
int result = func(3, 5);
std::cout << "结果: " << result << std::endl;
return 0;
}
在更函数式编程语言(如 JavaScript、Python 等 )里,函数作为一等公民体现更直接,C++ 因语言特性,借助 std::function 、函数对象等贴近这一概念,让函数能灵活参与赋值、传递等操作 。 若用 C++11 前语法,也可用函数指针:
#include <iostream>
// 普通函数
int add(int a, int b) { return a + b; }
int main() {
// 函数指针存储函数
int (*func)(int, int) = add;
int result = func(3, 5);
std::cout << "结果: " << result << std::endl;
return 0;
}
这里函数 add 能赋值给函数指针 func ,类似普通值操作,一定程度模拟一等公民特性,不过 C++ 里函数本身不是严格意义(如不能直接创建函数字面量等 )的一等公民,是通过这些方式靠拢 。
lc1179
一句一句的模拟
注意题目要求返回的是idx
class Solution {
public:
int nearestValidPoint(int x, int y, vector<vector<int>>& p)
{
int d = INT_MAX, r = -1;
for (int i = 0; i < p.size(); ++i) {
int a = p[i][0], b = p[i][1];
if (a == x || b == y) {
int t = abs(a - x) + abs(b - y);
if (t < d || (t == d && i < r)) {
d = t;
r = i;
}
}
}
return r;
}
};
lc2419.二进制周
- 有上一题的
- 按位或 logtrick不变或变大的性质
- 可以想到
- 按位与 不变或变小的性质。
--计算机二进制思维的学习
总结:越或越大,越与越小
所以本题求最大元素的最长连续长度即可
class Solution {
public:
int longestSubarray(vector<int>& nums) {
int mx = ranges::max(nums);
int ans = 0, cnt = 0;
for (int x : nums)
{
if (x == mx)
{
cnt++;
ans = max(ans, cnt);
}
else
cnt = 0;
}
return ans;
}
};