算法专题六: 模拟与分治快排

news2024/10/17 17:25:59

目录

  • 模拟
  • 1. 替换所有的问号
  • 2. 提莫攻击
  • 3. Z字形变换
  • 4. 外观数列
  • 5. 数青蛙
  • 分治快排
  • 1. 颜色分类
  • 2. 排序数组
  • 3. 数组中的第K个最大元素
  • 4. 库存管理Ⅲ

模拟

1. 替换所有的问号

在这里插入图片描述

算法思路: 本题就是简单的模拟, 只需按照题目的思路遍历所有的字符, 如果为?则将其替换, 替换时寻找26个小写字母中符合要求的, 即前一个字符和后一个字符都不等于当前字符, 如果为第一个字符和最后一个字符就不需要判断.

class Solution {
public:
    string modifyString(string s) {
        int n = s.size();
        for(int i = 0; i < n; i++)
        {
            if(s[i] == '?')
            {
                for(char ch = 'a'; ch < 'z'; ch++)
                {
                    if((i == 0 || s[i - 1] != ch) && (i == n - 1 || s[i + 1] != ch))
                    {
                        s[i] = ch;
                        break;
                    }
                }
            }
        }
        return s;
    }
};

2. 提莫攻击

在这里插入图片描述

算法思路: 根据题意, 如果后一个与前一个间隔小于d秒, 则只能释放它们之间的时间差值, 如果时间大于等于d秒,则可以释放d秒, 最后加上最后一个释放的时间.

class Solution {
public:
    int findPoisonedDuration(vector<int>& nums, int d) {
        int n = nums.size(), ret = 0;
        for(int i = 1; i < n; i++)
        {
            int k = nums[i] - nums[i-1];
            if(k < d) 
                ret += k;
            else ret += d; 
        }
        return ret + d;
    }
};

3. Z字形变换

在这里插入图片描述

算法思路: 本题也可以使用模拟, 可以创建一个二维矩阵, 将所有的字符全部放到矩阵中, 然后再遍历矩阵, 但是时间复杂度和空间复杂度都为O(len * N).
第二种, 找规律, 百分之九十九的模拟题的优化都是找规律, 我们把下标列出来, 就可以直观的发现规律, 求出公差d, 然后根据公差d计算出每一行.

在这里插入图片描述

class Solution {
public:
    string convert(string s, int numRows) {
        if(numRows == 1) return s;
        string ret;
        int n = s.size();
        int d = 2 * numRows - 2;
        for(int k = 0; k < n; k += d)
            ret += s[k];
        for(int i = 1; i < numRows - 1; i++)
        {
            for(int k = i, j = d - i; k < n || j < n; k += d, j += d)
            {
                if(k < n) ret += s[k];
                if(j < n) ret += s[j];
            }
        }
        for(int k = numRows - 1; k < n; k += d)
            ret += s[k];
        return ret; 
    }
};

4. 外观数列

在这里插入图片描述

算法思路:
在这里插入图片描述
对于任意一个字符串, 我们仅需转换成几个什么的形式即可, 使用双指针算法, 滑动窗口, 然后转换成字符串, 进行n次变换.

class Solution {
public:
    string countAndSay(int n) {
        string ret = "1";
        for(int i = 0; i < n - 1; i++)
        {
            int len = ret.size();
            string tmp; 
            for(int left = 0 ,right = 0; right < len;)
            {
                while(ret[right] == ret[left]) right++;
                tmp += to_string(right - left) + ret[left];
                left = right;
            }
            ret = tmp; 
        }
        return ret;
    }
};

5. 数青蛙

在这里插入图片描述

算法思路: 采用哈希的思想, 如果当前字符为c,则hash[c]++, 再判断k字符是否存在, 如果存在则k–, 当遍历到其余字符时取查看前一个字符是否存在, 进行讨论, 然后遍历字符串, 除k之外如果还有多余的字符则返回-1.

在这里插入图片描述

class Solution {
public:
    int minNumberOfFrogs(string croakOfFrogs) {
        string s = "croak";
        int n = s.size();
        vector<int> hash(n);
        unordered_map<char,int> index;
        for(int i = 0 ; i < n; i++)
            index[s[i]] = i;
        for(auto x : croakOfFrogs)
        {
            if(x == 'c')
            {
                if(hash[n-1])  hash[n-1]--;
                hash[0]++;
            }
            else
            {
                int i = index[x];
                if(hash[i-1] == 0) return -1;
                hash[i-1]--;hash[i]++;
            }
        }
        for(int i = 0; i < n - 1 ; i++)
        {
            if(hash[i] != 0)
            return -1;
        }
        return hash[n-1];
        
    }
};

分治快排

1. 颜色分类

在这里插入图片描述

在这里插入图片描述

算法思路: 将数组分为三个区域, 采用三指针法, 如果=0, 则交换nums[++left]和nums[i++]. 如果nums[i] == 1, 则i直接++, 进行下一个字符的扫描, 如果等于1, 则交换nums[–right]和nums[i], 此时i不能++,因为当前字符仍然是待扫描字符, 我们的扫描是从左到右扫描, 当i和right位置相同时就不需要扫描, 此后就划分为三个区域.

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int n = nums.size();
        int left = -1, right = n, i = 0;
        while(i < right)
        {
            if(nums[i] == 0)
                swap(nums[++left],nums[i++]);
            else if(nums[i] == 1) i++;
            else swap(nums[--right],nums[i]);
        } 
    }
};

2. 排序数组

在这里插入图片描述

在这里插入图片描述

算法思路: 我们采用上一道题三路划分的思想, 将数组划分为三块, 然后取最左边和最右边在进行排序, 采用随机数取基准值的方法.

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        srand(time(NULL));
        qsort(nums,0,nums.size() - 1);
        return nums;
    }
    void qsort(vector<int>& nums,int l,int r)
    {
        if(l >= r) return;
        int tmp = getrandom(nums,l,r);
        int i = l, left = l - 1, right = r + 1;
        while(i < right)
        {
            if(nums[i] < tmp) swap(nums[++left], nums[i++]);
            else if(nums[i] == tmp) i++;
            else swap(nums[--right],nums[i]);
        }
        //[l,left] [left+1,right-1],[right,r]
        qsort(nums,l,left);
        qsort(nums,right,r);
    }
    int getrandom(vector<int>& nums,int l,int r)
    {
        int tmp = rand();
        return nums[tmp % (r - l + 1) + l];
    }
};

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

在这里插入图片描述

算法思路: 本道题我们可以有多种解法, 比如排序, 堆, 但是这里我们采用快速选择算法, 根据算法导论一书的证明, 该方法的时间复杂度渐近与O(N).

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        srand(time(NULL));
        return qsort(nums,0,nums.size() - 1,k);
    }
    int qsort(vector<int>& nums,int l,int r, int k)
    {
        //随机数选择
        int key = getrandom(nums,l,r);
        int left = l - 1, right = r + 1, i = l;
        //划分区间
        while(i < right)
        {
            if(nums[i] < key) swap(nums[++left],nums[i++]);
            else if(nums[i] == key) i++;
            else swap(nums[--right],nums[i]);
        }
        //分类讨论
        //[l,left] [left+1,right-1] [right,r]
        int c = r - right + 1;
        int b = right - left - 1;
        if(k <= c) return qsort(nums,right,r,k);
        else if(b + c >= k) return key;
        else return qsort(nums,l,left,k-b-c);
    }
    int getrandom(vector<int>& nums,int l,int r)
    {
        return nums[rand() % (r - l + 1) +l];
    }
};

4. 库存管理Ⅲ

在这里插入图片描述

在这里插入图片描述

class Solution {
public:
    vector<int> inventoryManagement(vector<int>& nums, int cnt) 
    {
        srand(time(NULL));
        qsort(nums,0,nums.size()-1,cnt);
        return {nums.begin(),nums.begin()+cnt};
    }
    void qsort(vector<int>& nums,int l,int r, int cnt)
    {
        if(l >= r) return;
        int key = getrandom(nums,l,r);
        //划分区间
        int i = l, left = l - 1, right = r + 1;
        while(i < right)
        {
            if(nums[i] < key) swap(nums[++left],nums[i++]);
            else if(nums[i] == key) i++;
            else swap(nums[--right],nums[i]);
        }
        //分类讨论
        int a = left - l + 1, b = right - left - 1;
        if(cnt < a) return qsort(nums,l,left,cnt);
        else if(cnt <= a + b) return;
        else return qsort(nums,right,r,cnt-a-b);
    }
    //随机数取基准值
    int getrandom(vector<int>& nums,int l,int r)
    {
        return nums[rand() % (r - l + 1) + l];
    }
};

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

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

相关文章

今日指数项目day8实战权限管理器(上)

3.权限管理器 3.1 权限列表展示功能 1&#xff09;原型效果 2&#xff09;接口说明 功能描述&#xff1a; 查询所有权限集合 服务路径&#xff1a; /api/permissions 服务方法&#xff1a;Get 请求参数&#xff1a;无响应数据格式: {"code": 1,"data":…

Python自然语言处理之pyltp模块介绍、安装与常见操作案例

pyltp是哈尔滨工业大学社会计算与信息检索研究中心推出的一款基于Python封装的自然语言处理工具&#xff0c;它提供了哈工大LTP&#xff08;Language Technology Platform&#xff09;工具包的接口。LTP工具包以其强大的中文分词、词性标注、命名实体识别、依存句法分析等功能&…

Idea不能创建java8切换路径

顶部的Server URL改成https://start.aliyun.com/

Ubuntu配置应用开机自启动

有些自己下载的应用想要配置开机自启动&#xff0c;比如snipaste&#xff0c;steam等&#xff0c;可以通过一下步骤进行配置 点击应用展开图标 这个里面就是开机自启动的一些应用&#xff0c;可以将自己想要自启动的应用添加到这个里面来 以上是snipaste配置&#xff0c;起…

大数据治理:构建数据驱动的智能决策体系

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

RocketMq详解:三、RocketMq通用生产和消费方法改造

文章目录 1.背景2.通用方法改造2.1添加maven依赖2.2 RocketMq基础配置2.3 配置类2.5 消息传输的对象和结果2.4 消息生产者2.5 消息消费者2.6 功能测试 1.背景 在第二章&#xff1a;《RocketMq详解&#xff1a;二、SpringBoot集成RocketMq》中我们已经实现了消费基本生产和消费…

CISCN2022-cactus

这周在疯狂学kernel pwn。 记录一下这题&#xff0c;race conditonmsg_msgpipe_buffer&#xff0c;kaslrsmepsmapkpti。 漏洞很简单&#xff0c;所有操作都没加锁&#xff0c;就是race condition了。edit什么的都只能2次。 很明显了&#xff0c;一次泄露基址&#xff0c;一次劫…

unidbg console debugger 调试技巧

版权归作者所有&#xff0c;如有转发&#xff0c;请注明文章出处&#xff1a;https://cyrus-studio.github.io/blog/ 打开debug日志 编辑 unidbg-android/src/test/resources/log4j.properties 把 log4j.logger.com.github.unidbg.AbstractEmulator 改为 DEBUG 当运行报错时…

lenovo联想 ThinkPad E14 Gen 2,E15 Gen 2 AMD(20T6,20T7,20T8,20T9)原厂Win10系统镜像下载

适用机型&#xff1a;【20T6、20T7、20T8、20T9】 链接&#xff1a;https://pan.baidu.com/s/1AVTvmiIHjafsFw8P7_jMPg?pwdzux5 提取码&#xff1a;zux5 联想原装WIN系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、系统属性专属LOGO标志、Office办公软件、联想电脑…

C#实现CRC32算法

CRC32 是一种校验和算法&#xff0c;用于检测消息是否未被修改。 它被广泛使用&#xff1a;例如&#xff0c;计算以太网发送包校验和。 public class CRC32 {private static readonly uint[] Crc32Table new uint[256];static CRC32(){uint i, j;uint crc;for (i 0; i < …

《深度学习》OpenCV 风格迁移、DNN模块 案例解析及实现

目录 一、风格迁移 1、什么是风格迁移 2、步骤 1&#xff09;训练 2&#xff09;迁移 二、DNN模块 1、什么是DNN模块 2、DNN模块特点 1&#xff09;轻量 2&#xff09;外部依赖性低 3&#xff09;方便 4&#xff09;集成 5&#xff09;通用性 3、流程图 4、图像…

软件设计之Redis(1)

软件设计之Redis(1) 路线图推荐&#xff1a; 【Java学习路线-极速版】【Java架构师技术图谱】 尚硅谷Redis零基础到进阶&#xff0c;最强redis7教程&#xff0c;阳哥亲自带练&#xff08;附redis面试题&#xff09; 资料可以去尚硅谷官网免费领取 学习内容&#xff1a; Redi…

Unity3D 观察者模式

Unity3D 泛型事件系统 观察者模式 观察者模式是一种行为设计模式&#xff0c;通过订阅机制&#xff0c;可以让对象触发事件时&#xff0c;通知多个其他对象。 在游戏逻辑中&#xff0c;UI 界面通常会监听一些事件&#xff0c;当数据层发生变化时&#xff0c;通过触发事件&am…

【JavaSE基础】Java 变量

为什么需要变量 变量是程序的基本组成单位 class Test{public static void main(String[] args){int a 1; //定义一个变量&#xff0c;类型为int&#xff0c;变量名为a&#xff0c;并赋值为1int b 3; //定义另一个变量&#xff0c;类型为int&#xff0c;变量名为b&#xff0…

sqli-labs less-25 and/or绕过

来到less-25 我们可以看到下面有提示&#xff0c;Hint: Your Input is Filtered with following result: 说明本关卡有过滤&#xff0c; 构造 http://192.168.140.130/sq/Less-25/?id1’ 页面报错&#xff0c;从报错可以得知闭合方式为,所以 用注释符&#xff0c;发现注释符…

oracle数据坏块处理(一)-通过rman备份修复

表有坏块时&#xff0c;全表查询会报错&#xff1a; 这时候如果有前面正常的rman备份&#xff0c;那么我们就可以通过rman备份直接对数据文件块做恢复 先对数据文件做个逻辑检查&#xff1a; RMAN> backup check logical VALIDATE DATAFILE EXB_DATA/exb/datafile/cuteinf…

公开课 | 2024最新清华大模型公开课 第3课 神经网络与大模型基础 Part 2

本文由readlecture.cn转录总结。ReadLecture专注于音、视频转录与总结&#xff0c;2小时视频&#xff0c;5分钟阅读&#xff0c;加速内容学习与传播。 大纲 神经网络概述 神经网络的概念 神经网络的应用方式 序列建模与神经网络架构 循环神经网络&#xff08;RNN&#xff09;…

UE5模型导入面板解读

1.Skeletal Mesh&#xff1a; 是一个可以让模型动起来的选项&#xff0c;适用于需要动画的角色或生物。是否勾选&#xff1a;如果导入的是一个需要动画的角色或生物&#xff0c;就勾选 Skeletal Mesh 选项&#xff1b;如果是静态物体&#xff0c;就不勾选。 2.Build Nanite&a…

集合类HashMap,HashTable,ConcurrentHashMap区别?

1.HashMap 简单来说&#xff0c;HashMap由数组链表组成的&#xff0c;数组是HashMap的主体&#xff0c;链表则是主要为了解决哈希冲突而存在的&#xff0c;如果定位到的数组位置不含链表&#xff08;当前entry的next指向null&#xff09;,那么对于查找&#xff0c;添加等操作很…

VS中创建QT项目。

一&#xff0c;安装QT&#xff0c; 重点&#xff1a;在安装QT的时候要安装msvc201x版本的组件&#xff0c; 二 &#xff0c; 安装 qt-vs-tools Index of /development_releases/vsaddin/2.8.1 三。安装 win10sdk&#xff0c;这是因为我的当前电脑是win10的&#xff0c; 安装版…