首页 > 编程语言 >【算法】【优选算法】模拟

【算法】【优选算法】模拟

时间:2024-12-20 22:31:10浏览次数:5  
标签:优选 return int ret ++ 算法 croakOfFrogs hash 模拟

目录


一、模拟简介

模拟就是依葫芦画瓢,题目会将如何做给出来,直接做出来就行。

做题过程:

  • 先模拟算法流程,
  • 再将流程转化为代码。

二、1576.替换所有的问号

题目链接:1576.替换所有的问号
题目描述:

题目解析:

  • 给我们一个字符串,每除字符’?‘外其它两个字符之间是不相等的,且字符全是小写字母和’?'。
  • 将字符串中的’?'全部替换成小写字母。并保证两两不相等的条件。

解题思路:

  • 我们直接模拟题目讲解的过程,
  • 遍历字符串,找到’?'字符,就替换,
  • 替换的时候,就从26个小写字母找跟’?'字符前后字符不相等的字符即可。
  • 边界情况,在头是’?‘时,只需要跟后一个字符比较,在尾是’?',只需要和前一个字符比较。

解题代码:

//时间复杂度:O(n)
//空间复杂度:O(n)
class Solution {
    public String modifyString(String ss) {
        char[] s = ss.toCharArray();
       
        for(int i = 0; i < s.length; i++) {
            if(s[i] == '?') {
                for( char ch = 'a'; ch <= 'z'; ch++) {
                    if( (i == 0 || s[i-1] != ch) && (i == s.length-1 || s[i+1] != ch) ) {
                        s[i] = ch;
                        break;
                    }
                }
            }
        }
        return String.valueOf(s);
    }
}

三、495.提莫攻击

题目链接:495.提莫攻击
题目描述:

题目解析:

  • 给一个非递减数组,也就是从前往后元素要么相等,要么变大。
  • 数组元素表示发起攻击,让艾希中毒的时刻。
  • 在本来中毒期间,再次中毒,会刷新中毒时长。
  • 求取艾希总中毒时长。

解题思路:

  • 当下一次中毒时刻(也就是下一个元素),在上一次中毒效果区间内也就是 [t, t + duration - 1],那么,就要刷新时长,不在就将中毒效果吃满。
  • 刷新时长前我们记录下这次会中毒的时间也就是timeSeries[i+1] - timeSeries[i]。
  • 到最后一个元素一定会吃满中毒效果(中毒时间为duration)。

解题代码:

//时间复杂度:O(n)
//空间复杂度:O(1)
class Solution {
    public int findPoisonedDuration(int[] timeSeries, int duration) {
        int ret = 0;
        for(int i = 0; i < timeSeries.length - 1; i++) {
            if(timeSeries[i+1] <= timeSeries[i] + duration - 1) {
                ret += timeSeries[i+1] - timeSeries[i]; 
            } else {
                ret += duration;
            }
        }
        ret += duration;
        return ret;
    }
}

四、6.N字形变换

题目链接::6.N字形变换
题目描述:

题目解析:

  • 将题目给的字符串,按照给定的行数,按照之形排列。
  • 就以下标来举例:

解题思路:

  • 根据上面的图我们找规律,第一行和最后一行的每个插入元素相差的个数是一样的2*numRows-2,这个就是公差d。
  • 中间行:第⼀个数取值为⾏数,每组下标为(2n - 1, 2n)的数围绕(2numRows - 2)的倍数左右取值,(即第一个数是行数 i ,第二个数是公差 d - i,然后每个加公差向后走)。
    细节处理:当numRows为1的时候,如果按照上面循环就陷入死循环了,直接返回原字符串即可。

解题代码:

//时间复杂度:O(n*m)
//空间复杂度:O(n)
import java.util.*;
class Solution {
    public String convert(String s, int numRows) {
        StringBuffer ret = new StringBuffer();
        int n = s.length();//数组长
        int d = 2 * numRows - 2; //公差d
        if(numRows == 1) return s;

        //第一行
        for(int i = 0; i <  n; i += d) {
            ret.append(s.charAt(i));
        }

        //中间行
        for(int i = 1; i < numRows - 1; i++) {
            for(int j = i, k = d-i;  j < n || k < n; j += d, k += d) {
                if(j < n) ret.append(s.charAt(j));
                if(k < n) ret.append(s.charAt(k));
            }
        }
        //最后一行
        for(int i = numRows-1; i < n; i += d) {
            ret.append(s.charAt(i));
        }

        return ret.toString();
    }
}

五、38.外观数列

题目链接:38.外观数列
题目描述:

题目解析:

  • 行程长度编码:就是将字符串从前向后遍历,连续相同的字符合并为个数+字符形式,单独字符个数为1。
  • 第n个的字符串就是n-1的结果,n等于1的结果就是1。

解题思路:

  • 递归调用,递归结束条件就是n为1的时候。
  • 其他先拿到字符串countAndSay(n-1)。
  • 在使用滑动窗口,
    • 进窗口条件:right < len && s[right] == s[left]
    • 出窗口条件:不满足进窗口时。
    • 出窗口:left = right
    • 更改结果:在出窗口前更改。

解题代码:

//时间复杂度:O(n)
//空间复杂度:O(1)
class Solution {
    public String countAndSay(int n) {
        if(n == 1) return "1";

        char[] s = countAndSay(n-1).toCharArray();
        
        int len = s.length;
        StringBuffer ret = new StringBuffer();
        int count = 0;
        for(int left = 0, right = 0; right < len;) {
            //进窗口
            while(right < len && s[right] == s[left]) {
                right++;
            }
            //更改结果
            ret.append(right - left);
            ret.append(s[left]);
            //出窗口
            left = right;
            
        }
        return ret.toString();
    }
}

六、1419.数⻘蛙

题目链接:1419.数⻘蛙
题目描述:

题目解析:

  • 返回实现croak最少得青蛙个数(也就是croak中有多少是穿插进行)。

解题思路:

  • 当遇到’r’ ‘o’ ‘a’ ‘k’ 这四个字符的时候,我们要去看看每⼀个字符对应的前驱字符,有没有⻘蛙叫出来。如果有⻘蛙叫出来,那就让这个⻘蛙接下来喊出来这个字符;如果没有,直接返回-1 ;
  • 当遇到’c’ 这个字符的时候,我们去看看’k’ 这个字符有没有⻘蛙叫出来。如果有,就让这个⻘蛙继续去喊’c’ 这个字符;如果没有的话,就重新搞⼀个⻘蛙。
  • 细节处理:
    • 可能最后croak没走完,没进行到k。croakOfFrogs = “croakcroa”。
    • 可能有多个c,croakOfFrogs = “cccccccrrooaakk”。
  • 可以加一个for循环判断,也可以使用判断长度处理细节1,再判断一下hash[ 0 ]即可。

解题代码:

//时间复杂度:O(n)
//空间复杂度:O(1)
class Solution {
    public int minNumberOfFrogs(String croakOfFrogs) {
        if(croakOfFrogs.length() % 5 != 0) return -1;
        
        int[] hash = new int[5];
        for(int i = 0; i < croakOfFrogs.length(); i++) {
            if(croakOfFrogs.charAt(i) == 'c') {
                if(hash[4] > 0) hash[4]--;
                hash[0]++;
            }else if(croakOfFrogs.charAt(i) == 'r') {
                if(hash[0] == 0) return -1;
                hash[0]--;
                hash[1]++;
            } else if(croakOfFrogs.charAt(i) == 'o') {
                if(hash[1] == 0) return -1;
                hash[1]--;
                hash[2]++;
            } else if(croakOfFrogs.charAt(i) == 'a') {
                if(hash[2] == 0) return -1;
                hash[2]--;
                hash[3]++; 
            } else {
                if(hash[3] == 0) return -1;
                hash[3]--;
                hash[4]++;
            }
        }
        // for(int i = 0; i < 4; i++) {
        //     if(hash[i] != 0) return -1;
        // }        
        return hash[0] != 0 ? -1 : hash[4];
    }
}
//时间复杂度:O(n*m)
//空间复杂度:O(n)
import java.util.*;
class Solution {
    public int minNumberOfFrogs(String croakOfFrogs) {
        if(croakOfFrogs.length() % 5 != 0) return -1;
        int[] hash = new int[5];

        String s = "croak";
        Map<Character, Integer> index = new HashMap<>();
        for(int i = 0; i < s.length(); i++) {
            index.put(s.charAt(i), i);
        }

        for(int i = 0; i < croakOfFrogs.length(); i++) {
            if(croakOfFrogs.charAt(i) == s.charAt(0)) {
                if(hash[4] > 0) hash[4]--;
                hash[0]++;
            } else {
                int in = index.get(croakOfFrogs.charAt(i));
                if(hash[in-1] == 0) return -1;
                hash[in-1]--;
                hash[in]++;
            }
        }
        // for(int i = 0; i < 4; i++) {
        //     if(hash[i] != 0) return -1;
        // }
        return hash[0] != 0 ? -1 : hash[4];
    }
}

标签:优选,return,int,ret,++,算法,croakOfFrogs,hash,模拟
From: https://blog.csdn.net/yj20040627/article/details/143615308

相关文章

  • 用C#实现感知器算法——从零开始打造一个简单的机器学习模型!
    感知器(Perceptron)是一个经典的机器学习算法,常用于二分类问题。它是神经网络的基础,最早由FrankRosenblatt在1958年提出。今天,我们将用C#实现一个简单的感知器算法,让你理解感知器的工作原理,并能够亲自编码一个可用的模型。一、感知器算法概述感知器是一种线性分类器,其核心思想是......
  • 最优雅的算法——快速排序
    快速排序:探索两种流行的方法快速排序,这个听起来有点技术性的术语,实际上是一个既高效又优雅的算法,它能够将一堆混乱的数据快速整理得井井有条。今天,我们将通过一种轻松愉快的方式,一起揭开快速排序的神秘面纱,并探索两种流行的实现方法。话不多说,开始战斗快速排序的魔法:基......
  • 【字符串匹配算法——BF算法】
    ......
  • 分批将数据导入Excel,模拟数据
    1、pom.xml<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.0.0</version></dependency><dependency><groupId>org.apa......
  • 机器学习之聚类(k均值聚类、层次聚类、密度聚类、EM算法、高斯混合模型)思维导图
    学习笔记—机器学习-聚类(k均值聚类、层次聚类、密度聚类、EM算法、高斯混合模型)思维导图20241220,以后复习看。(西瓜书+统计学习方法)学的迷糊的,如果错别字,请忽略。PS:图片看不清,可以下载下来看。往期思维导图:机器学习之集成学习Bagging(随机深林、VR-树、极端随机树)思维导......
  • 操作系统里的算法
    处理机管理调度算法先来先服务调度算法(firstcomefirstserver,FCFS)简介;先来先服务调度算法是最简单的调度算法,系统按照作业到达的先后次序进行调度。优点:有利于长作业,适合繁忙的工作缺点:不利于短作业短作业优先调度算法(shortjobfirst,SJF)简介:按照作业的长短来计......
  • 排序算法
    1.快速排序intPartition(SqListL,intlow,inthigh){L.elem[0]=L.elem[low];intl=low,r=high;while(l<r){while(r>l&&L.elem[r]>=L.elem[0])r--;L.elem[l]=L.elem[r];while(l<r&&L.elem[l]<=L.elem[0])l++;L.elem[r]=L.elem[l];......
  • K - means 聚类算法
    一、引言在数据挖掘和机器学习领域,聚类算法是一种重要的无监督学习方法,用于将数据集中的数据点划分为不同的组或簇。K-means聚类算法是其中最为经典和广泛应用的算法之一,它简单且高效,能够快速地对大规模数据集进行处理。本文将详细介绍K-means聚类算法的原理、应用场景......
  • 【机器学习与数据挖掘实战】案例05:基于决策树、梯度提升和XGBoost分类算法的O2O优惠券
    【作者主页】FrancekChen【专栏介绍】⌈⌈⌈机器学习与数据挖掘实战案例⌋......
  • 算法网关视频分析网关:安防监控摄像机有哪些最新技术趋势?
    在当今这个信息化快速发展的时代,安防监控摄像机技术正经历着一场革命性的变化。这些变化不仅提高了监控系统的效能,也为安全管理带来了新的视角和解决方案。随着人工智能、物联网、高清视频技术等前沿科技的融合,安防监控摄像机的最新技术趋势正在重塑我们对安全监控的认知。以下是......