i
去重:检查 nums[i]
是否与前一个元素相同,避免重复。while (j < k)
遍历。j
和 k
去重:在找到有效三元组后,跳过重复的 j
和 k
。代码逻辑:
while j < k:
if sum == 0:
//处理结果并移动j和k
while j < k and nums[j] == nums[j+1]: j +=1
while j < k and nums[k] == nums[k-1]: k -=1
j +=1; k -=1
ldp
和右侧最大值数组 rdp
。min(ldp[i], rdp[i]) - height[i]
累加。lmax
和 rmax
分别表示左右遍历时的最大值。height[left] <= height[right]
时处理左指针,反之处理右指针。ans += (lmax - height[left])
或 ans += (rmax - height[right])
。set
记录当前窗口字符。while
循环处理重复字符的移除。class Solution {
public:
int lengthOfLongestSubstring(string s) {
int j=0;
int maxLength =0;
unordered_set<char> charIndexSet;
for(int i=0; i<s.size();i++){
while(charIndexSet.find(s[i]) != charIndexSet.end()){
charIndexSet.erase(s[j]);
j++;
}
charIndexSet.insert(s[i]);
maxLength =max(maxLength,i-j+1);
}
return maxLength;
}
};
i >= k-1
),队首即为最大值。t
中字符出现次数,维护窗口内字符覆盖状态。t
,然后收缩左指针找最小窗口。count
变量记录匹配字符数,避免每次检查全表。nums[i]
交换到索引 nums[i]-1
的位置。nums[i] == i+1
的位置。n+1
。matrix[i][j]
与 matrix[j][i]
。matrix[i][j]
与 matrix[i][n-j-1]
。index
表示当前处理的数字位置。start
参数不变。mid_val = matrix[mid//n][mid%n]
。mid_val
与 target
的关系调整搜索范围。[
时,当前字符串入栈并重置。]
时,弹出数字和字符串,拼接后更新结果。ans[stack.pop()] = i - idx
k
的最小堆,按频率排序。class Solution {
struct myComparison{
bool operator()(pair<int,int>&p1,pair<int,int>&p2){
return p1.second>p2.second;//小顶堆是大于号
}
};
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> map;
for(int i=0; i<nums.size(); i++){
map[nums[i]]++;
}
priority_queue<pair<int, int>, vector<pair<int, int>>,myComparison> pri_que;
for(auto& it: map){
pri_que.push(it);
if(pri_que.size() >k){
pri_que.pop();
}
}
vector<int> res;
while(!pri_que.empty()){
res.emplace_back(pri_que.top().first);
pri_que.pop();
}
return res;
}
};
x->pre =dummy; x->next=dummy->next;x->pre->next =x;x->next->pre =x;
x->pre->next = x->next;x->next->pre = x->pre;
用hashmap通过key找到node,先remove结点node,然后再push_front结点
用DLinkedNode* back_node = dummy->pre;
获取最后一个结点struct Dlinked {
int key, value;
Dlinked *next, *pre;
Dlinked(int _key, int _value) : key(_key), value(_value), next(nullptr), pre(nullptr) {}
};
class LRUCache {
private:
int capacity;
Dlinked* dummy;
unordered_map<int, Dlinked*> key_to_node;
void remove_node(Dlinked* x) {
x->pre->next = x->next;
x->next->pre = x->pre;
}
void push_front(Dlinked* x) {
x->next = dummy->next;
x->pre = dummy;
x->pre->next = x;
x->next->pre = x;
}
Dlinked* get_node(int key) {
auto it = key_to_node.find(key);
if (it == key_to_node.end()) return nullptr;
Dlinked* node = it->second;
remove_node(node);
push_front(node);
return node;
}
public:
LRUCache(int capacity) {
this->capacity = capacity;
dummy = new Dlinked(0, 0);
dummy->pre = dummy;
dummy->next = dummy;
}
int get(int key) {
Dlinked* node = get_node(key);
return node ? node->value : -1;
}
void put(int key, int value) {
Dlinked* node = get_node(key);
if (node) {
node->value = value;
return;
}
node = new Dlinked(key, value);
key_to_node[key] = node;
push_front(node);
if (key_to_node.size() > capacity) {
Dlinked* back_node = dummy->pre;
remove_node(back_node);
key_to_node.erase(back_node->key);
delete back_node;
}
}
};
pair<int,int> expandFormCenter(string s,int left, int right){
while(left >=0 && right < s.size()&& s[left] == s[right]){
left --;
right ++;
}
return {left+1, right-1};
}
string longestPalindrome(string s) {
int start = 0,end = 0;
for (int i = 0; i < s.size(); i++) {
auto [left1, right1] = expandFormCenter(s, i, i);
auto [left2, right2] = expandFormCenter(s, i, i + 1);
int len1 = right1 - left1 + 1;
int len2 = right2 - left2 + 1;
int curr_len = end - start + 1;
if (left1 <= right1 && len1 > curr_len) {
start = left1;
end = right1;
}
if (left2 <= right2 && len2 > curr_len) {
start = left2;
end = right2;
}
}
return s.substr(start,end-start + 1);
}
class Solution {
public:
int getKthElement(const vector<int>& nums1, const vector<int>& nums2, int k) {
/* 主要思路:要找到第 k (k>1) 小的元素,那么就取 pivot1 = nums1[k/2-1] 和 pivot2 = nums2[k/2-1] 进行比较
* 这里的 "/" 表示整除
* nums1 中小于等于 pivot1 的元素有 nums1[0 .. k/2-2] 共计 k/2-1 个
* nums2 中小于等于 pivot2 的元素有 nums2[0 .. k/2-2] 共计 k/2-1 个
* 取 pivot = min(pivot1, pivot2),两个数组中小于等于 pivot 的元素共计不会超过 (k/2-1) + (k/2-1) <= k-2 个
* 这样 pivot 本身最大也只能是第 k-1 小的元素
* 如果 pivot = pivot1,那么 nums1[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums1 数组
* 如果 pivot = pivot2,那么 nums2[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums2 数组
* 由于我们 "删除" 了一些元素(这些元素都比第 k 小的元素要小),因此需要修改 k 的值,减去删除的数的个数
*/
int m = nums1.size();
int n = nums2.size();
int index1 = 0, index2 = 0;
while (true) {
// 边界情况
if (index1 == m) {
return nums2[index2 + k - 1];
}
if (index2 == n) {
return nums1[index1 + k - 1];
}
if (k == 1) {
return min(nums1[index1], nums2[index2]);
}
// 正常情况
int newIndex1 = min(index1 + k / 2 - 1, m - 1);
int newIndex2 = min(index2 + k / 2 - 1, n - 1);
int pivot1 = nums1[newIndex1];
int pivot2 = nums2[newIndex2];
if (pivot1 <= pivot2) {
k -= newIndex1 - index1 + 1;
index1 = newIndex1 + 1;
}
else {
k -= newIndex2 - index2 + 1;
index2 = newIndex2 + 1;
}
}
}
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int totalLength = nums1.size() + nums2.size();
if (totalLength % 2 == 1) {
return getKthElement(nums1, nums2, (totalLength + 1) / 2);
}
else {
return (getKthElement(nums1, nums2, totalLength / 2) + getKthElement(nums1, nums2, totalLength / 2 + 1)) / 2.0;
}
}
}
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* dummy = new ListNode(0);
ListeNode* cur = dummy;
int carry = 0;
while(l1 || l2 || carry){
int sum = carry;
sum += l1 ? l1->val:0;
sum += l2 ? l2->val:0;
if(l1) l1=l1->next;
if(l2) l2=l2->next;
carry = sum /10;
cur->next = new ListNode(sum % 10);
cur = cur->next;
}
}
}
void quickSort(std::vector<int>& arr, int left, int right) {
if (left >= right) return;
int pivot = arr[left];
int i = left + 1;
int j = right;
while (i <= j) {
while (i <= j && arr[i] <= pivot) i++;
while (i <= j && arr[j] >= pivot) j--;
if (i < j) std::swap(arr[i], arr[j]);
}
std::swap(arr[left], arr[j]);
quickSort(arr, left, j - 1);
quickSort(arr, j + 1, right);
}
void merge(std::vector<int>& arr, int left, int mid, int right) {
std::vector<int> temp(right - left + 1);
int i = left, j = mid + 1, k = 0;
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
}
}
while (i <= mid) {
temp[k++] = arr[i++];
}
while (j <= right) {
temp[k++] = arr[j++];
}
for (i = left, k = 0; i <= right; ++i, ++k) {
arr[i] = temp[k];
}
}
void mergeSort(std::vector<int>& arr, int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
}
void heapify(std::vector<int>& arr, int n, int i) {
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left] > arr[largest]) {
largest = left;
}
if (right < n && arr[right] > arr[largest]) {
largest = right;
}
if (largest != i) {
std::swap(arr[i], arr[largest]);
heapify(arr, n, largest);
}
}
void heapSort(std::vector<int>& arr) {
int n = arr.size();
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(arr, n, i);
}
for (int i = n - 1; i > 0; i--) {
std::swap(arr[0], arr[i]);
heapify(arr, i, 0);
}
}