算法学习——LeetCode力扣补充篇8(146. LRU 缓存、 215. 数组中的第K个最大元素、25. K 个一组翻转链表)

本文主要是介绍算法学习——LeetCode力扣补充篇8(146. LRU 缓存、 215. 数组中的第K个最大元素、25. K 个一组翻转链表),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

算法学习——LeetCode力扣补充篇8

在这里插入图片描述

146. LRU 缓存

146. LRU 缓存 - 力扣(LeetCode)

描述

请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:
LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。

示例

示例:

输入
[“LRUCache”, “put”, “put”, “get”, “put”, “get”, “put”, “get”, “get”, “get”]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
输出
[null, null, null, 1, null, -1, null, -1, 3, 4]

解释
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 缓存是 {1=1}
lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
lRUCache.get(1); // 返回 1
lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
lRUCache.get(2); // 返回 -1 (未找到)
lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
lRUCache.get(1); // 返回 -1 (未找到)
lRUCache.get(3); // 返回 3
lRUCache.get(4); // 返回 4

提示

1 <= capacity <= 3000
0 <= key <= 10000
0 <= value <= 105
最多调用 2 * 105 次 get 和 put

代码解析

链表法(超时)
class LRUCache {
public:list<pair<int,int>> my_list;int max_size = 0;LRUCache(int capacity) {max_size = capacity;}int get(int key) {auto it = my_list.begin();for(int i=0 ; i<my_list.size() ;i++,it++){if(it->first == key) {pair<int,int> tmp = *it;my_list.erase(it);my_list.push_front(tmp);return tmp.second;}}return -1;}void put(int key, int value) {auto it = my_list.begin();for(int i=0 ; i<my_list.size() ;i++,it++){if(it->first == key){my_list.erase(it);break;}}my_list.push_front({key,value});if(my_list.size() > max_size) my_list.pop_back();return ;}
};/*** Your LRUCache object will be instantiated and called as such:* LRUCache* obj = new LRUCache(capacity);* int param_1 = obj->get(key);* obj->put(key,value);*/
自制双向链表
class LRUCache {
public:struct  Node{int key;int value;Node* pre;Node* next;Node():key(0),value(0),pre(nullptr),next(nullptr) {}Node(int x,int y):key(x),value(y),pre(nullptr),next(nullptr) {}};LRUCache(int capacity) {_capacity = capacity;head = new Node();tail = new Node();head->next = tail;tail->pre  = head;}int get(int key) {if(my_map.find(key) == my_map.end() ) return -1;Node* tmp = my_map[key];remove_node(tmp);add_head(tmp);return tmp->value;}void put(int key, int value) {if(my_map.find(key) == my_map.end() ) //不存在{Node* new_node = new Node(key,value);my_map[key] = new_node;add_head(new_node);size++;if(size > _capacity){my_map.erase(tail->pre->key);remove_node(tail->pre);}}else{Node* tmp = my_map[key];tmp->value = value;remove_node(tmp);add_head(tmp);}}void add_head(Node* new_node){new_node->pre = head;new_node->next = head->next;head->next->pre = new_node;head->next = new_node;}void remove_node(Node* node){node->pre->next = node->next;node->next->pre = node->pre;}
private:int _capacity;Node* head;Node* tail;int size=0;unordered_map<int,Node*> my_map;};/*** Your LRUCache object will be instantiated and called as such:* LRUCache* obj = new LRUCache(capacity);* int param_1 = obj->get(key);* obj->put(key,value);*/

215. 数组中的第K个最大元素

215. 数组中的第K个最大元素 - 力扣(LeetCode)

描述

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例

示例 1:

输入: [3,2,1,5,6,4], k = 2
输出: 5

示例 2:

输入: [3,2,3,1,2,4,5,5,6], k = 4
输出: 4

提示

1 <= k <= nums.length <= 105
-104 <= nums[i] <= 104

代码解析

库函数
class Solution {
public:int findKthLargest(vector<int>& nums, int k) {sort(nums.begin(),nums.end());return nums[nums.size()-k];}
};
快速排序
class Solution {
public:void swap(int &a , int &b){int tmp = b;b = a;a = tmp;}int part(vector<int>& nums , int left , int right){int key = nums[left];while(left<right){while(left < right && nums[right] <= key) right--;swap(nums[left] , nums[right]);while(left < right && nums[left] >= key) left++;swap(nums[left] , nums[right]);}return left;}void quick_sort(vector<int>& nums , int left , int right){if(left > right) return;int mid = part(nums,left,right);quick_sort(nums,left,mid-1);quick_sort(nums,mid+1,right);}int findKthLargest(vector<int>& nums, int k) {quick_sort(nums,0,nums.size()-1);return nums[k-1];}
};
快速排序
class Solution {
public:void quickSort(vector<int>& arr, int left, int right) {// 定义枢轴int pivot = arr[(left + right) / 2];//int pivot = arr[left]; 也可以// 定义两个指针int i = left;int j = right;// 当左指针比右指针小时继续循环while (i <= j){// 左指针从左往右扫描,直到找到一个元素比枢轴大while (arr[i] > pivot) i++;// 右指针从右往左扫描,直到找到一个元素比枢轴小while (arr[j] < pivot) j--;// 如果两个指针没有相遇,交换它们所指向的元素if (i <= j){int temp = arr[i];arr[i] = arr[j];arr[j] = temp;i++;j--;}}// 如果左边还有元素,递归左边的排序if (left < j) quickSort(arr, left, j);// 如果右边还有元素,递归右边的排序if (i < right) quickSort(arr, i, right);}int findKthLargest(vector<int>& nums, int k) {quickSort(nums,0,nums.size()-1);return nums[k-1];}
};

25. K 个一组翻转链表

25. K 个一组翻转链表 - 力扣(LeetCode)

描述

给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。

k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

示例

示例 1:
在这里插入图片描述

输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]

示例 2:

在这里插入图片描述

输入:head = [1,2,3,4,5], k = 3
输出:[3,2,1,4,5]

提示

链表中的节点数目为 n
1 <= k <= n <= 5000
0 <= Node.val <= 1000

进阶:你可以设计一个只用 O(1) 额外内存空间的算法解决此问题吗?

代码解析

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* reverseKGroup(ListNode* head, int k) {stack<int> my_stack;vector<int> v_nums;ListNode* tmp = head;int num = 0;while(tmp != nullptr && num < k){num++;v_nums.push_back(tmp->val);my_stack.push(tmp->val);if(num == k){while(num--) v_nums.pop_back();num = k;while(num--){v_nums.push_back(my_stack.top());my_stack.pop();}cout<<num<<' ';num = 0;}tmp = tmp->next;}tmp = head;int i=0;while(tmp != nullptr){tmp->val = v_nums[i];tmp = tmp->next;i++;}return head;}
};

这篇关于算法学习——LeetCode力扣补充篇8(146. LRU 缓存、 215. 数组中的第K个最大元素、25. K 个一组翻转链表)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/909957

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖