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

news2024/11/26 0:32:15

算法学习——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;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1600238.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于深度学习的乳腺癌淋巴结转移预测模型(E-Transformer)

乳腺癌细胞淋巴结转移是界定乳腺癌早中期的重要标准&#xff0c;需要活检&#xff0c;患者体验较差。 传统的图像辅助诊断需要手动提取特征、组合图像特征&#xff0c;效率低下、效果不佳。新兴的基于深度学习的图像辅助诊断&#xff0c;利用卷积神经网络通过全连接层或机器学…

ubuntu23.10.1 php8.2安装

1、更新镜像源 apt update2、安装php 如果在这里不知道自己Linux能安装什么版本的php,可以使用apt install php,会给你提示&#xff0c;根据提示自己选择版本安装 apt install php我这里是php8.2-cli apt install php8.2-cli其他扩展包&#xff0c;在后面加个-可以查看&…

跟TED演讲学英文:How AI can bring on a second Industrial Revolution by Kevin Kelly

How AI can bring on a second Industrial Revolution Link: https://www.ted.com/talks/kevin_kelly_how_ai_can_bring_on_a_second_industrial_revolution Speaker: Kevin Kelly Date: June 2016 文章目录 How AI can bring on a second Industrial RevolutionIntroduction…

福布斯发布2024年人工智能初创企业50强

随着人工智能热潮的持续&#xff0c;一种新的技术经济正在帮助企业开发和部署人工智能驱动的应用程序。在《福布斯》第六届年度“人工智能50强”榜单上&#xff0c;这类新锐企业正大行其道。该榜单遴选了AI领域最有前途的初创公司&#xff0c;由《福布斯》在领先行业专家的帮助…

文献速递:深度学习胰腺癌诊断--胰腺癌在CT扫描中通过深度学习检测:一项全国性的基于人群的研究

Title 题目 Pancreatic Cancer Detection on CT Scans with Deep Learning: A Nationwide Population-based Study 胰腺癌在CT扫描中通过深度学习检测&#xff1a;一项全国性的基于人群的研究 01 文献速递介绍 胰腺癌&#xff08;PC&#xff09;的五年生存率是所有癌症中…

redis五种类型介绍

Redis是一种内存数据存储系统&#xff0c;它支持五种不同的数据类型&#xff1a; 1. String String是Redis中最基本的数据类型&#xff0c;它可以存储任何形式的字符串数据&#xff0c;例如普通的文本字符串&#xff0c;二进制数据或JSON格式的数据。除此之外&#xff0c;还可以…

AtCoder Educational DP Contest

A - Frog 1 大意 有块石头&#xff0c;第块石头的高度为。从石头跳到石头的花费是。 一只青蛙在石头上&#xff0c;每次可以跳步或步&#xff0c;请问跳到石头的最小代价是多少&#xff1f; 思路 设&#xff0c;为青蛙跳到第号石头时的最小代价。 每一个点都可以由前两个点…

动态规划Dynamic programming详解-编辑距离问题【python】

作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任大厂数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python 欢迎加入社区&#xff1a;码上找工作 作者专栏每日更新&#xff1a; LeetCode解锁1000题: 打怪升级之旅 python数据分析…

【笔试训练】day3

今天的题又简单了很多欸 1.简写单词 没思路 代码&#xff1a; #include <iostream> #include<string> using namespace std;int main() {string str;string ans;getline(cin,str);if(str[0]>Z)ans(str[0]-32);else ansstr[0];for(int i1;i<str.size();i…

Linux第88步_非阻塞IO实验

非阻塞IO是“应用程序”对“驱动设备”进行操作&#xff0c;若不能获取到设备资源&#xff0c;则非阻塞IO应用程序的线程不会被“挂起”&#xff0c;即线程不进入休眠&#xff0c;而是一直“轮询”&#xff0c;直到获取到设备资源为止&#xff0c;或者直接放弃。 非阻塞IO应用举…

mybatis(9)-逆向工程+PageHelper+注解方式开发

最后一篇&#xff01;&#xff01; 1、逆向工程1.1、普通版1.2、增强版 2、PageHelper2.1 limit2.2 插件 3、注解开发3.1 Insert3.2Delete3.3 Update3.4 Select Results 1、逆向工程 1.1、普通版 所谓的逆向工程是&#xff1a;根据数据库表逆向生成Java的pojo类&#xff0c;S…

纯golang开发的mqtt server

Mochi-MQTT Server github地址&#xff1a;https://github.com/mochi-mqtt/server Mochi-MQTT 是一个完全兼容的、可嵌入的高性能 Go MQTT v5&#xff08;以及 v3.1.1&#xff09;中间件/服务器。 Mochi MQTT 是一个完全兼容 MQTT v5 的可嵌入的中间件/服务器&#xff0c;完…

YoloV9实战:从Labelme到训练、验证、测试、模块解析

模型实战 训练COCO数据集 本次使用2017版本的COCO数据集作为例子&#xff0c;演示如何使用YoloV8训练和预测。 下载数据集 Images: 2017 Train images [118K/18GB] &#xff1a;http://images.cocodataset.org/zips/train2017.zip2017 Val images [5K/1GB]&#xff1a;htt…

选择最佳 PoE 布线系统的 3 个步骤

选择合适的 POE 布线系统的重要性 在不断发展的信息和通信技术 &#xff08;ICT&#xff09; 领域&#xff0c;以太网供电 &#xff08;PoE&#xff09; 布线系统已成为一种革命性的解决方案&#xff0c;它简化了网络设备的部署和管理&#xff0c;同时优化了电力传输。从智能建…

傅里叶变换到底是什么

傅里叶变换到底是什么 有一个f&#xff08;t&#xff09;经傅里叶变换公式转化成F&#xff08;w&#xff09;&#xff1b; F&#xff08;w&#xff09;包括 欧拉公式转化成无限包括sin cos的函数相加。sin cos前面的参数a不为0说明这个周期函数分量存在&#xff0c;是某一种有…

基本模拟概念

目标&#xff1a; 讨论模拟电子技术的基本特性 描述模拟信号 分析信号源 解释放大器的特性 1.1模拟电子学 电子学可以划分成很多的分类来研究。其中最基本的一种分类方式是将信号分成可由 二进制数字表示的数字信号和由连续变化量表示的模拟信号。数字电子学包括所有的算术 和…

想做好抖音直播运营,这81个专业术语你必须得知道 沈阳新媒体运营培训

1.起号 释义&#xff1a;从0基础创建账号到1账号已具备基础模型&#xff0c;启动一个直播间&#xff0c;并使其能稳定卖出去东西的过程。简单一点来说&#xff0c;就是冷启动&#xff0c;通过活动或者其他方式获得快速大量曝光的一种形式。目前主流起号方式为&#xff1a;▼活…

【C++】unordered_set和unordered_map

底层哈希结构 namespace hash_bucket {template<class T>struct HashData{T _data;struct HashData* next nullptr;HashData(const T& data):_data(data){}};//仿函数:这里直接用开散列仿函数template <class K>struct HashFunc{size_t operator()(const K&a…

attention and tell论文【无标题】

这个公式使用LaTeX语法表示为&#xff1a; ( i t f t o t c t ) ( σ σ σ tanh ⁡ ) T D m n , n ( E y t − 1 h t − 1 x t ) \begin{pmatrix}i_t \\f_t \\o_t \\c_t\end{pmatrix} \begin{pmatrix}\sigma \\\sigma \\\sigma \\\tanh\end{pmatrix}T_{Dmn,n}\begin{pmatri…

HackMyVM-Gift

目录 信息收集 arp nmap WEB dirsearch hydra ssh连接 get root 信息收集 arp ┌─[rootparrot]─[~] └──╼ #arp-scan -l Interface: enp0s3, type: EN10MB, MAC: 08:00:27:16:3d:f8, IPv4: 192.168.9.102 Starting arp-scan 1.10.0 with 256 hosts (https://git…