【Java 优选算法】模拟

news/2025/2/25 6:00:30

欢迎关注个人主页:逸狼


创造不易,可以点点赞吗~

如有错误,欢迎指出~



模拟算法的思路比较简单,根据题目描述列出流程,找出规律,将流程转化为代码 

替换所有的问号

题目链接

解法

直接根据题目给出条件模拟 示例,找出规律

 1.先找出字符?,再让满足条件的字符ch替换 字符?,该条件为(字符? != 前一个字符) 并且 (字符? != 后一个字符) ,

在代码中就是(s[i - 1] != ch) && ( s[i + 1] != ch)

2.处理边界情况 : 当字符? 处在0下标处时,因为没有前一个字符,所以可以直接满足第一个条件

同理当字符? 处在n-1下标处时,因为没有后一个字符,所以可以直接满足第二个条件

在代码中就是(i == 0 || s[i - 1] != ch) && (i == n - 1 || s[i + 1] != ch)

画图举例

代码

class Solution {
    public String modifyString(String ss) {
        char[] s = ss.toCharArray();
        int n = s.length;
        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 String.valueOf(s);
    }
}

提莫攻击

题目链接

解法

找出规律 当时间间隔x>=d时,结果ret+d,当x<d时,ret+x

画图举例

代码

class Solution {
    public int findPoisonedDuration(int[] timeSeries, int duration) {
        int ret= 0;
        for(int i = 1; i < timeSeries.length; i++){
            int x = timeSeries[i] - timeSeries[i - 1];
            if(x >= duration){
                ret += duration;
            }else{
                ret += x;
            }
        }
        return ret + duration;//最后一次攻击,加上完整的中毒时间
    }
}

N字形变换

题目链接

解法

解法1: 利用数组模拟过程,按顺序一个个填入数组,再按要求输出

解法2: 在解法1的基础上找规律,将要输出的字符串分为3段, 在第一行中,  找到第一个字符和第二个字符的公差d = 2n - 2

  • 第一段: 第一行;第一个放在0下标位置,第二个0+d,依次类推
  • 第二段:中间的k行;以每两个为一组,第一组分别是k和d-k,后面依次+d
  • 第三段:最后一行;第一个是n-1位置,后面依次+d

注意边界情况 当n =1 时,直接输出原字符串

规律如下图

代码

class Solution {
    public String convert(String s, int numRows) {
        // 处理边界情况numRows=1
        if (numRows == 1)
            return s;

        int d = 2 * numRows - 2, n = s.length();
        StringBuilder ret = new StringBuilder();
        // 处理第一行
        for (int i = 0; i < n; i += d) {
            ret.append(s.charAt(i));
        }
        // 处理中间k行
        for (int k = 1; k < numRows - 1; k++) {//依次枚举中间行
            for (int i = k, j = d - k; i < n || j < n; i += d, j += d) {
                if (i < n)
                    ret.append(s.charAt(i));
                if (j < n)
                    ret.append(s.charAt(j));
            }
        }
        //3.处理最后一行
        for(int i = numRows - 1; i < n; i += d){
            ret.append(s.charAt(i));
        }
        return ret.toString();
    }
}

外观数列

题目链接

解法

模拟+ 双指针

举例如下图数组nums, 定义left=0,right=0,

  1. 当nums[left]==nums[right]时,right向后移动,直到不相等,
  2. 此时先拼接3的次数即right - left次,
  3. 再拼接该字符,依次类推

代码

class Solution {
    public String countAndSay(int n) {
        String ret = "1";
        for(int i = 1; i < n; i++){//从第一行开始,描述n-1次即可
            StringBuilder tmp = new StringBuilder();
            int len = ret.length();
            for(int left = 0, right = 0; right < len; ){
                while(right < len && ret.charAt(left) == ret.charAt(right)) right++;
                tmp.append(Integer.toString(right - left));//拼接被描述字符的次数
                tmp.append(ret.charAt(left));//拼接被描述的字符
                left = right;
            }
            ret = tmp.toString();
        }
        return ret;
    }
}

数青蛙

题目链接

解法

借用hash表用来时刻记录每个字符的出现情况

例如字符串crcoakroakcroak,从前往后扫描,以下为模拟过程

  1. 0位置字符为c,操作为c个数+1 ,
  2. 1位置字符为r,需要确认前面的字符是否有字符c,操作即为c个数-1,r个数+1
  3. 2位置字符为c,此时操作为c个数+1
  4. 重复以上操作,直到k的数为2(代表此时有两只青蛙)
  5. 最后一声croak可以叫前面2只的其中一只重复叫的(因为题目要求返回最少青蛙数), 此时操作 k - 1
  6. 当扫描到第三个k时, k+1, 最终返回 2

代码

class Solution {
    public int minNumberOfFrogs(String croakOfFrogs) {
        char[] c =croakOfFrogs.toCharArray();
        String t = "croak";
        int n = t.length();
        int[] hash = new int[n];//数组模拟哈希表
        Map<Character, Integer> index = new HashMap<>();//<x,x字符对应的下标>
        for(int i = 0; i < n; i++){
            index.put(t.charAt(i), i);
        }
        for(char ch : c){
            if(ch == t.charAt(0)){
                if(hash[n - 1] != 0) hash[n - 1]--;
                hash[0]++;
            }else{
                int i = index.get(ch);
                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];
    }
}


http://www.niftyadmin.cn/n/5865070.html

相关文章

Android开发数据持久化

Android系统中主要提供了三种方式用于简单的实现数据持久化功能&#xff0c; 分别是&#xff1a;文件存储&#xff0c;SharedPreferences存储以及数据库存储。 文件存储&#xff1a;核心技术就是用Context 类中提供openFileInput()和openFileOutput()方法&#xff0c;之后利用…

以 Tomcat 为例分析 Java 中的线程池

以 Tomcat 为例分析 Java 中的线程池 首先&#xff0c;为什么会有“池”的概念&#xff1f; 我们的项目在运行过程中&#xff0c;需要使用系统资源&#xff08;CPU、内存、网络、磁盘等&#xff09;来完成信息的处理&#xff0c;比如在 JVM 中新建对象就需要消耗 CPU 和内存资…

docker 一键部署wvp+zlm

拉取容器 docker pull 648540858/wvp_pro启动容器 docker run --env WVP_IP"自己电脑的ip" -it -p 18080:18080 -p 30000-30500:30000-30500/udp -p 30000-30500:30000-30500/tcp -p 80:80 -p 5060:5060 -p 5060:5060/udp 648540858/wvp_pro3.浏览器访问测试摄像头…

【Docker】如何在Linux、Windows、MacOS中安装Docker

Linux安装Docker 在终端中执行一键安装脚本命令安装docker sudo curl -fsSL https://gitee.com/tech-shrimp/docker_installer/releases/download/latest/linux.sh | bash -s docker --mirror Aliyun1.1 配置docker镜像源 在终端执行 一行命令&#xff0c;编辑配置文件 sudo …

图数据库Neo4j面试内容整理-索引(Index)

索引(Index) 是数据库中用来提高查询性能的技术,特别是在处理大量数据时,索引能够大大加速查询操作。在 Neo4j 这样的图数据库中,索引也起着非常重要的作用,尤其是在图中查找节点时,使用索引可以避免全图扫描,从而提高查询效率。 1. Neo4j 中的索引概念

相似性搜索(2)

在本篇中&#xff0c;我们通过播客相似性搜索为例&#xff0c;进一步研究基于chroma 的相似性搜索&#xff1a; 参考&#xff1a; https://www.kaggle.com/code/switkowski/building-a-podcast-recommendation-engine/notebook 数据集来源&#xff1a; https://www.kaggle.…

【JavaEE】SpringMVC 请求传参

目录 一、请求二、传递单个参数三、传递多个参数四、传递对象五、RequestParam注解 后端参数重命名&#xff08;后端参数映射&#xff09;六、传递数组七、传递集合&#xff0c;RequestParam八、传递JSON数据8.1 JSON字符串和Java对象互转8.1.1 Test注解8.1.2 Java对象转JSON8.…

opencv交叉编译报错:undefined reference to `png_riffle_palette_neon

序偶NEON 概述 NEON&#xff08;Nested Enhanced Vector Instruction Set&#xff09;是 ARM 架构中的一种高级 SIMD&#xff08;Single Instruction, Multiple Data&#xff0c;单指令多数据&#xff09;扩展技术。它专为加速多媒体和信号处理任务而设计&#xff0c;允许在单…