模拟算法系列|替换所有的问号|提莫攻击|种花问题|Z字形变换|兼具大小写的英文字母|删除字符使频率相同

大家好,我是LvZi,今天带来模拟算法系列|替换所有的问号|提莫攻击|种花问题|Z字形变换|兼具大小写的英文字母|删除字符使频率相同
在这里插入图片描述

一.基本概念

模拟算法就是根据题意 模拟出代码的过程,模拟算法的题意往往都很简单,考验的是将思路转化为代码的能力,十分的锻炼代码能力,且能很好的培养分类讨论的思想

关于模拟算法的提高,最重要的就是多刷题,多看题解 ,积累足够多的经验

二.例题讲解

01.替换所有的问号
链接:https://leetcode.cn/problems/replace-all-s-to-avoid-consecutive-repeating-characters/
分析

  • 题意很简单,就是将所有的?替换为其他字符,要求替换后不存在连续重复的字符
  • 本题采用分类讨论的思想,假设?的下标为i,根据i的位置可以分为三类
  • i == 0:成立条件:tmp != s[1]
  • i == n - 1:成立条件:tmp != s[n - 2]
  • 0 < i < n - 1:成立条件:tmp != s[i - 1] && tmp != s[i + 1]

代码:

class Solution {
    public String modifyString(String ss) {
        // 模拟实现
        int n = ss.length();
        if (n == 1) return "a";
        char[] s = ss.toCharArray();
        for (int i = 0; i < n; i++) {
            char ch = s[i];
            if (ch == '?') {
                for (char tmp = 'a'; tmp <= 'z'; tmp++) {
                    if (i == 0) {
                        if(tmp != s[i + 1]) s[i] = tmp;
                    } else if (i == n - 1) {
                        if(tmp != s[n - 2]) s[i] = tmp;
                    } else {
                        if(tmp != s[i - 1] && tmp != s[i + 1]) s[i] = tmp;
                    }
                }
            }
        }

        return new String(s);
    }
}

02.提莫攻击
链接:https://leetcode.cn/problems/teemo-attacking/
分析

  • 分类讨论,可分为两种情况
  • 1.当前时间并未中毒 无需重置时间
  • 2.当前时间处于中毒时间 需要重置时间

代码:

class Solution {
    public int findPoisonedDuration(int[] timeSeries, int d) {
        int n = timeSeries.length, ret = d;
        for(int i = 1; i < n; i++) {
            if(timeSeries[i] <= timeSeries[i - 1] + d) {
                ret += (timeSeries[i] - timeSeries[i - 1]);// 中毒  重置时间
                continue;
            }
            ret += d;// 未中毒
        }

        return ret;
    }
}

03.种花问题
链接:https://leetcode.cn/problems/can-place-flowers/
分析

  • 跳格子问题,为了尽可能的将所有花都种植,采用的策略应该是"找离得最近的可以种花的位置"
  • 边界处理十分麻烦,但是我们可以扩充数组,类似于二维数组经常使用的扩增一行一列的方式来进行初始化,减少边界条件的判断

代码:

class Solution {
    public boolean canPlaceFlowers(int[] flowerbed, int n) {
        // 为了简化判断的逻辑我们经常使用的优化技巧就是"扩增原数组"
        // 最经常用于dp问题
        // 在本题中有两个边界条件  i==0和i==m- 1
        // 为了防止越界,前后各添加一个0
        int[] a = new int[flowerbed.length + 2];
        for(int i = 1; i <= flowerbed.length; i++) a[i] = flowerbed[i - 1];
        for (int i = 1; i < a.length - 1; i++) {
            if (a[i - 1] == 0 && a[i] == 0 && a[i + 1] == 0) {
                a[i] = 1; // 种花!
                n--;
            }
        }
        return n <= 0;
    }
}


04.Z字形变换
链接:https://leetcode.cn/problems/zigzag-conversion/description/
分析

  • 找规律的题目
    在这里插入图片描述
  • 为了更方便起见,将字符串的长度+1

代码:

class Solution {
    public String convert(String ss, int numRows) {
        if(ss.length() == 1 || numRows == 1) return ss;// 长度为1  或者不需要进行Z字形变换
        String s = " " + ss;
        char[] str = s.toCharArray();
        StringBuilder sb = new StringBuilder();
        int stap = 2 * numRows - 2, n = str.length;
        // 处理第一行
        for(int i = 1; i < n; i += stap) sb.append(str[i]);
        // 处理中间行
        for(int i = 2; i <= numRows - 1; i++) {
            int n1 = i, n2 = 2 * numRows - i;
            while(n1 < n) {
                sb.append(str[n1]);
                if(n2 < n) sb.append(str[n2]);
                n1 += stap; n2 += stap;
            }
        }
        // 处理最后一行
        for(int i = numRows; i < n; i += stap) sb.append(str[i]);
        return sb.toString();
    }
}

注意:这里踩了一个坑,测试用例一直显示超出内存限制,刚开始以为是写了死循环,一直检查循环的条件是否正确,但是发现并不存在错误,又打开idea进行测试,发现也没错误;看了题解才发现是由于特殊condition的存在,比如只有一个字符,或者numRows == 1,第二种情况才是导致超出内存限制的罪魁祸首,此时stap == 0,所以会造成死循环,超出内存限制,写这种题目一定要考虑好特殊情况


05.兼具大小写的英文字母
链接:https://leetcode.cn/problems/greatest-english-letter-in-upper-and-lower-case/description/
分析

  • 使用hash统计字符串s中每一个字符出现的次数,然后遍历判断每一个字符是否大小写都存在,如果存在,返回最大的那个

代码

class Solution {
    public String greatestLetter(String s) {
        // 不需要傻傻的去比较大小  直接从最大的字母Z开始遍历即可
        int[] hash = new int[128];
        for(char ch : s.toCharArray()) hash[ch]++;
        for(char ch = 'Z'; ch >= 'A'; ch--)
            if(hash[ch] >= 1 && hash[ch + 32] >= 1)
                return "" + ch;

        return "";
    }
}
  • 方法2:使用位运算
  • 采用位图的思想,使用mask1的二进制位上的0和1表示小写字母是否出现过,使用mask2的二进制位上的0和1表示大写字母是否出现过

代码

class Solution {
    public String greatestLetter(String s) {
        int mask1 = 0, mask2 = 0;
        for(char ch : s.toCharArray()) {
            if(ch >= 'a' && ch <= 'z') mask1 |= (1 << (ch - 'a'));
            else mask2 |= (1 << (ch - 'A'));
        }

        int mask = mask1 & mask2;
        for(int i = 31; i >= 0; i--) {
            if(((1 << i) & mask) != 0) return "" + ((char)('A' + i));
        }
        return "";
    }
}

06.删除字符使频率相同
链接:https://leetcode.cn/problems/remove-letter-to-equalize-frequency/
分析
思路:

  1. 统计每个字符出现的频率
  2. 建立"频率--出现次数"的映射关系
  3. 分类讨论
    • 只有一种频率:此时仅有一种condition不符合条件,当频率为偶数且频率出现的次数也为偶数,形如aabb这种
    • 存在两种频率:此时有两种符合条件的情况;
      • 其中一个频率为1,且出现次数为1
      • 其中一个频率比另一个频率大1,且次频率的出现次数也为1
    • 其他频率:都不符合情况

代码:

class Solution {
    public boolean equalFrequency(String word) {
        // 1.统计所有字符出现的频率
        int[] hash1 = new int[128];
        for(char ch : word.toCharArray()) hash1[ch]++;

        // 2.建立"频率--出现次数"的映射关系
        Map<Integer, Integer> hash2 = new HashMap<>();
        for(int x : hash1) {
            if(x != 0) 
                hash2.put(x, hash2.getOrDefault(x, 0) + 1);
        }

        // 3.分类讨论结果
        // 频率只有一种  
        if(hash2.size() == 1) {
            for(Integer key : hash2.keySet()) {
                if(key % 2 == 0 && hash2.get(key) > 1) return false;
                return true;
            }
        }

        // 频率有两种
        if(hash2.size() == 2) {
            int[] key = new int[2], val = new int[2];
            int index = 0;
            for(Map.Entry<Integer, Integer> entries : hash2.entrySet()) {
                key[index] = entries.getKey();
                val[index] = entries.getValue();
                ++index;
            }

            if((key[0] == 1 && val[0] == 1)||(key[1] == 1 && val[1] == 1)) return true;
            if((key[0] - key[1] == 1 && val[0] == 1)||(key[1] - key[0] == 1 && val[1] == 1)) return true;
        }

        // 其余频率都不满足情况
        return false;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Zigbee智能家居数据中心:微信小程序实时掌控家居传感器信息

摘要&#xff1a; 本文将介绍如何构建一个基于Zigbee和微信小程序的智能家居网关&#xff0c;实现对家居传感器数据的采集、汇总和展示。用户可通过微信小程序实时查看家中温湿度、光照等环境数据&#xff0c;为智能家居系统提供数据支撑。 关键词&#xff1a; Zigbee&#xf…

信创测试与性能测试的差别是什么?

信创测试和性能测试在多个方面存在显著的区别。 首先&#xff0c;信创测试是一个更为全面和系统的测试过程&#xff0c;它主要针对信创工程项目中的产品、系统等进行测试和验证&#xff0c;以确保其自主可控和满足性能要求。这包括适配测试、功能测试、性能测试、安全测试、兼…

Spring Boot集成geode快速入门Demo

1.什么是geode&#xff1f; Apache Geode 是一个数据管理平台&#xff0c;可在广泛分布的云架构中提供对数据密集型应用程序的实时、一致的访问。Geode 跨多个进程汇集内存、CPU、网络资源和可选的本地磁盘&#xff0c;以管理应用程序对象和行为。它使用动态复制和数据分区技术…

【postgresql】索引

见的索引类型&#xff1a; B-tree 索引&#xff1a;这是最常用的索引类型&#xff0c;适用于大多数查询。B-tree索引可以高效地处理范围查询。 Hash 索引&#xff1a;适用于等值查询&#xff0c;但不支持范围查询。 GiST 索引&#xff1a;通用搜索树&#xff08;GiST&#xf…

Django学习第二天

启动项目命令 python manage.py runserver 动态获取当前时间 javascript实现数据动态更新代码 <script>setInterval(function() {var currentTimeElement document.getElementById(current-time);var currentTime new Date();currentTimeElement.textContent Curren…

基于Java废物回收机构管理系统详细设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;…

基于康养大模型和健康设备平台的智能蓝牙语音合成芯片VTX326

AI健康监护智能体是基于康养大模型和**智能语音芯片技术的健康设备平台&#xff0c;**旨在应对我国日益严峻的老龄化挑战。当前&#xff0c;中国总人口约为14.12亿&#xff0c;其中60周岁及以上老年人口占比19.8%&#xff0c;65周岁及以上老年人口占比14.9%&#xff0c;且老年人…

苹果p12证书最简单最新申请流程

使用uniapp打包&#xff0c;在ios上打正式包需要苹果的p12证书和证书profile文件&#xff0c;点进去uniapp的ios证书申请教程&#xff0c;通篇就是使用mac电脑申请的教程&#xff0c;假如没有mac电脑就无法继续了。 因此&#xff0c;假如没有mac电脑的同志们&#xff0c;可以参…

MATLAB—— 流程语句(1)

一、if elseif else end 语句 例子 x 88; % x表示成绩 if x>90 && x < 100 dj 1; % 等级为1级 elseif x>80 && x < 90 dj 2; % 等级为2级 elseif x>60 && x < 80 dj 3; % 等级为…

第4章 第一个程序

第4章 第一个程序 4.1 一个源程序从写出到执行的过程 第一步&#xff1a;编写汇编程序第二步&#xff1a;对源程序进行编译连接第三步&#xff1a;执行可执行文件中的程序 4.2.源程序 汇编语言中包含两种指令&#xff1a;汇编指令 和 伪指令 汇编指令&#xff1a;有对应机器…

中国国产AI芯片的崛起

一、CUDA的垄断 当讨论半导体行业面临的挑战时&#xff0c;你首先想到的是什么&#xff1f;光刻机&#xff1f;3纳米或者5纳米技术&#xff1f;我们无法生产的完美方形芯片&#xff1f;是的&#xff0c;但也不完全是。 人们经常把半导体芯片归类为硬件产业&#xff0c;但实际上…

C语言----文件操作

1.为什么使用文件&#xff1f; 如果没有⽂件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就丢失了&#xff0c;等再次运⾏程序&#xff0c;是看不到上次程序的数据的&#xff0c;如果要将数据进⾏持久化…

递归(二)—— 初识暴力递归

如何理解暴力递归&#xff1f; 字面意思就是——“暴力的递归”&#xff0c;就是——“别纠结细节&#xff0c;开整&#xff08;递归&#xff09;&#xff01;” 暴力递归就是尝试。即&#xff1a;只要满足递归条件就不断的递归下去&#xff0c;直到达到base case&#xff0c…

力扣习题--哈沙德数

一、前言 本系列主要讲解和分析力扣习题&#xff0c;所以的习题均来自于力扣官网题库 - 力扣 (LeetCode) 全球极客挚爱的技术成长平台 二、哈沙德数 1. 哈沙德数 如果一个整数能够被其各个数位上的数字之和整除&#xff0c;则称之为 哈沙德数&#xff08;Harshad number&…

LeetCode刷题之HOT100之除自身以外数组的乘积

2024 7/3 今天天气依旧很好&#xff0c;想起来做一题。 1、题目描述 2、算法分析 给定一个数组&#xff0c;要返回初自身以外数组的乘积。咋做呢&#xff1f;是的&#xff0c;我只能想到暴力解法&#xff0c;这不符合时间复杂度O(n)的要求&#xff0c;所以我只能看一下题解了…

零一万物: Yi Model API的使用

一、获取API Key 通过官方网址注册账号并且认证: 零一万物大模型开放平台 创建API Key 二、安装及调用 安装OpenAI SDK ​ 零一万物API 接口兼容 OpenAI 的 Python SDK&#xff0c;只需要简单配置即可使用。 安装 OpenAI SDK。请确保使用的 Python 版本至少为 3.7.1&a…

检索生成(RAG) vs 长文本大模型:实际应用中如何选择?

编者按&#xff1a;大模型的上下文理解能力直接影响到 LLMs 在复杂任务和长对话中的表现。本期内容聚焦于两种主流技术&#xff1a;长上下文(Large Context Windows)和检索增强生成(RAG)。这两种技术各有何优势&#xff1f;在实际应用中&#xff0c;我们又该如何权衡选择&#…

数据质量管理-可访问性管理

前情提要 根据GB/T 36344-2018《信息技术 数据质量评价指标》的标准文档&#xff0c;当前数据质量评价指标框架中包含6评价指标&#xff0c;在实际的数据治理过程中&#xff0c;存在一个关联性指标。7个指标中存在4个定性指标&#xff0c;3个定量指标&#xff1b; 定性指标&am…

【Windows】draw.io(免费的开源跨平台绘图软件)软件介绍

软件介绍 draw.io 是一款免费且易于使用的在线流程图绘图软件&#xff0c;后来更名为 diagrams.net。它最初作为一个基于 Web 的应用程序提供&#xff0c;支持用户创建各种类型的图表、流程图、网络图、组织结构图、UML 图等。它是完全免费的、强大的、专业的、易于使用的和高…

C++使用Poco库封装一个HTTP客户端类--Query参数

0x00 概述 我们使用Poco库的 Poco::Net::HTMLForm 类可以轻松实现表单数据的提交。 0x01 ApiPost提交表单数据 0x02 HttpClient类 #ifndef HTTPCLIENT_H #define HTTPCLIENT_H#include <string> #include <map> #include <Poco/URI.h> #include <Poco/N…