zoukankan      html  css  js  c++  java
  • [leetCode]38. 外观数列

    在这里插入图片描述

    解法一 递归+双指针

    f ( 1 ) = 1 f(1) = 1 f(1)=1
    f ( 2 ) = 1 1 f(2) = m11 f(2)=11
    f ( 3 ) = 2 1 f(3) = m21 f(3)=21
    f ( 4 ) = 1 2 1 1 f(4) = m12m11 f(4)=1211

    通过观察可以知道要知道f(n)则需要知道f(n-1)…f(1),因此可以想到递归;通过观察可知,每个外观字符串都是由前一个字符串的每一个字符"计数值"(加粗字符)加上所计数的字符,因此可以使用双指针法对相同字符计数并完成字符串拼接。

    class Solution {
        public String countAndSay(int n) {
            if(n == 1){
                return "1";
            }else{
                String preStr = countAndSay(--n);
                String ans = "";
                int len = preStr.length();
                int i = 0;//指针i指向preStr首字符(慢指针)
                for(int j = i+1; j < len; j++){//j为快指针用于跳过相同字符
                    if(preStr.charAt(j)!=preStr.charAt(i)){//跳过相同字符结束
                        ans = ans + (j-i) + preStr.charAt(i);//j-i为跳过相同字符的数量, preStr.charAt(i)为所跳过的字符
                        i = j;//移动i指针
                    }   
                }
                ans = ans + (len-i) + preStr.charAt(i);//上面遍历结束后可能还存在尾部连续字符,这一步就是拼接尾部字符
                return ans;
            }
        }
    }
    

    动态规化

    因为递归并没有涉及到重复计算,所以动态规化时间复杂度也没有优化。

    class Solution {
        public String countAndSay(int n) {
            String[] dp = new String[n];
            dp[0] = "1";
            for(int t = 1; t < n; t++){
                dp[t] = "";
                String preStr = dp[t-1];
                int len = preStr.length(); 
                int i = 0;
                for(int j = i + 1; j < len; j++){
                    if(preStr.charAt(j)!=preStr.charAt(i)){
                        dp[t]=dp[t]+(j-i)+preStr.charAt(i);
                        i = j;
                    }
                }
                dp[t]=dp[t]+(len-i)+preStr.charAt(i);
            }
            return dp[n-1];
        }
    }
    

    由于动态规化只记录了两个状态:前一个字符串和后一个字符串,因此可以用两个String 变量对空间复杂度进行优化:

    class Solution {
        public String countAndSay(int n) {
            String preStr = "1";
            String curStr = "";
            for(int t = 1; t < n; t++){
                int len = preStr.length(); 
                int i = 0;
                for(int j = i + 1; j < len; j++){
                    if(preStr.charAt(j)!=preStr.charAt(i)){
                        curStr= curStr + (j-i)+preStr.charAt(i);
                        i = j;
                    }
                }
                curStr=curStr + (len-i)+preStr.charAt(i);
                preStr = curStr;
                curStr = "";
            }
            return preStr;
        }
    }
    
  • 相关阅读:
    springboot实现定时任务,异步操作,统一结果返回,全局异常处理,拦截器及事务处理
    springboot集成mybatis,热部署以及整合Swagger2
    使用idea上传项目到码云(gitee)上
    RabbitMQ 高级应用
    Spring Boot整合RabbitMQ
    RabbitMQ--其他几种模式
    RabbitMQ入门--简单模式
    RabbitMQ安装(centos7)
    RocketMQ安装及入门
    [UWP]涨姿势UWP源码——极简的RSS阅读器
  • 原文地址:https://www.cnblogs.com/PythonFCG/p/13860024.html
Copyright © 2011-2022 走看看