leetcode中的状态机类型的题目

1 总结

一般是涉及到多个状态之间的转换,需要定义一个具有多个枚举值的变量,各个状态之间通过各种条件互相变化

2 LC57. 插入区间

在这里插入图片描述

2.1 解析

先是要确定新区间插入到哪一个位置(也有可能),插入后需要确定这个区间是否涉及到合并问题。
所以我们可以设计一个flag变量,确定区间是否插入,插入完成则进行到区间合并阶段。

2.2 代码:beat 95% commits in time complexity

class Solution {
    public int[][] insert(int[][] intervals, int[] newInterval) {
        int n=intervals.length;

        List<int[]>ans=new ArrayList<>();
        boolean f=false;//表示现待处理新区间的插入状态,f=true则表示处理完成,开启合并区间的状态
        for(int i=0;i<n;){
            int[] interval=intervals[i];
            if(!f){
                if(interval[1]<newInterval[0]){
                    ans.add(interval);
                    i++;
                }else if(interval[1]>=newInterval[0]&&interval[1]<=newInterval[1]){
                    int[]ni=new int[]{Math.min(interval[0],newInterval[0]),Math.max(interval[1], newInterval[1])};
                    ans.add(ni);
                    f=true;
                    i++;
                }else if(interval[0]>newInterval[1]){
                    ans.add(newInterval);
                    f=true;
                }else if(interval[0]<=newInterval[0]&&interval[1]>=newInterval[1]){
                    ans.add(interval);
                    f=true;
                    i++;
                }else if(interval[0]>=newInterval[0]&&interval[0]<=newInterval[1]){
                    ans.add(new int[]{newInterval[0],interval[1]});
                    f=true;
                    i++;
                }
            }else {
                // 转换为合并区间问题
                int[]li=ans.get(ans.size()-1);
                if(li[1]<interval[0]){
                    ans.add(interval);
                }else if(li[1]>=interval[0]){
                    int[]newi=new int[]{Math.min(li[0],interval[0]),Math.max(li[1],interval[1])};
                    ans.remove(ans.size()-1);
                    ans.add(newi);
                }
                i++;
                
            }
        }
        // 如果f一直是false,则说明新区间加在末尾
        if(!f){
            ans.add(newInterval);
        }
        int[][]res=new int[ans.size()][2];
        for(int i=0;i<ans.size();i++){
            res[i]=ans.get(i);
        }
        return res;
    }
}

3 LC722. 删除注释【2024滴滴国际化外卖部门秋招后端面试题】

3.1 分析

这道题的状态机的状态稍多,题目稍复杂

3.2 代码:beat 100% commits in time complexity

    // 假设注释内有了
    public List<String> removeComments(String[] source) {

        List<String>res=new ArrayList<>();
        StringBuilder sb=new StringBuilder();
        // 0:初始状态,1:行注释,2:块注释,3:引号
        // 1->0, 2->0, 

        int flag=0;
        int n=source.length;
        for(int i=0;i<n;i++){
            String str=source[i];
            char cs[]=str.toCharArray();
            int m=cs.length;

            for(int j=0;j<m;){
                // 只能在初始状态转为行注释状态
                if(j<m-1&&flag==0&&cs[j]=='/'&&cs[j+1]=='/'){
                    String addStr=sb.toString();
                    if(!"".equals(addStr)&&addStr!=null){
                        res.add(addStr);
                    }
                    sb=new StringBuilder();
                    flag=1;
                    j+=2;
                    break;
                }
                // 只能在初始状态转为多行注释状态
                if(j<m-1&&flag==0&&cs[j]=='/'&&cs[j+1]=='*'){

                    flag=2;
                    j+=2;
                    continue;
                }
                // 在多行注释的状态下转换为初始状态
                if(j<m-1&&flag==2&&cs[j]=='*'&&cs[j+1]=='/'){

                    flag=0;
                    j+=2;
                    continue;
                }
                // 开启引号状态
                if(j<m-1&&flag==0&&cs[j]=='"'){
                    flag=3;
                }
                // 关闭引号状态
                if(j<m-1&&flag==3&&cs[j]=='"'){
                    flag=0;
                }

                //处于引号或者初始状态的字符都可以被加入
                if(flag==0||flag==3){
                    sb.append(cs[j]);
                    j++;
                    continue;
                }
                j++;
            }
            // 当正常状态时,每一次换行都需要添加到res结果集中
            if(flag==0){
                String addStr=sb.toString();
                if(!"".equals(addStr)&&addStr!=null){
                    res.add(addStr);
                }
                sb=new StringBuilder();
            }
            // 当换行时,行注释状态自动回到初始状态
            if(flag==1){
                sb=new StringBuilder();
                flag=0;
            }
        }
        return res;
    }

4 LC6. Z 字形变换

在这里插入图片描述

4.1 使用一个状态变量记录当前的打印方向,当碰到边界时,自动换到另一个状态

class Solution {
    public String convert(String s, int numRows) {
        if(numRows==1)return s;
        int n=s.length();
        int curR=0;
        int i=0;
        List<StringBuilder>ans=new ArrayList<>();
        for(int j=0;j<numRows;j++){
            ans.add(new StringBuilder());
        }
        // 设置状态变量,f为true表示向下打印,f为false则表示相反
        boolean f=true;
        while(true){
            if(i==n){
                break; 
            }
            char c=s.charAt(i);
            ans.get(curR).append(c);    
            if(curR==numRows-1){
                f=false;
            }
            if(curR==0){
                f=true;
            }
            curR=f?curR+1:curR-1;
            i++;
        }
        StringBuilder sb=new StringBuilder();
        for(StringBuilder ss:ans){
            sb.append(ss);
        }
        return sb.toString();
    }
}
  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: LeetCode是一种流行的在线刷题平台,提供了许多算法和数据结构挑战,旨在帮助程序员和计算科学家提高他们的编程技能。以下是几个LeetCode题目及其答案: 1. 两数之和 题目描述:给定一个整数数组和一个目标值,找出数组的两个数,它们相加等于目标值。假设每个输入只对应一种答案,并且不能使用相同的元素。 答案:遍历数组,将每个数字存储到一个哈希表,同时计算出目标值与当前数字的差值。如果差值在哈希表,则返回这两个数字的索引。时间复杂度为O(n)。 2. 盛最多水的容器 题目描述:给定n个非负整数a1,a2,...,an,其每个点(i,ai)表示一个坐标。画n条垂直线,使得线i的两个端点在(i,ai)和(i,0)上。找到两条线,它们与x轴一起构成一个容器,使得容器包含最多水。 答案:使用双指针法,分别指向数组的头部和尾部。每次计算当前容器的大小,然后根据容器两侧的高度差决定是否移动指针。时间复杂度为O(n)。 3. 无重复字符的最长子串 题目描述:给定一个字符串,请找出其不含有重复字符的最长子串的长度。 答案:使用双指针法,分别指向子串的起始和结束位置。每次判断当前字符是否存在于子串,如果存在,则移动起始指针到重复字符的下一个位置,否则移动结束指针。同时记录最长子串的长度。时间复杂度为O(n)。 上述题目只是LeetCode的部分题目,不同的题目需要采用不同的算法和数据结构进行解决。通过刷LeetCode和其他类似的在线刷题平台,可以提高编程能力和算法思维能力,使得程序员更加熟练地处理各种算法问题。 ### 回答2: LeetCode是一个在线的编程题库,提供了各种不同难度和类型的编程题目。这些题目主要涵盖了算法、数据结构、字符串操作、图算法等方面的内容。 每道题目都有一个独特的编号和描述,通过阅读题目可以了解到输入和输出的形式,以及题目的具体要求。解答题目通常需要理解问题的本质,设计相应的算法,编写代码实现,并进行测试验证。 题目的难度分为简单、等和困难三个级别,根据不同的难度以及自己的编程能力,可以选择相应的题目来挑战。 解答题目的关键在于理解问题的本质,分析解决问题的思路,并设计合适的算法实现。这个过程需要对常见的算法和数据结构有一定的了解,比如动态规划、贪心算法、递归、队列等。 对于每一道题目LeetCode提供了多种语言的代码模板,如C++、Java、Python等,可以根据自己的编程习惯和喜好选择相应的语言进行代码编写。 解答题目的过程需要注意代码的效率和正确性,特别是对于大规模输入的情况,需要考虑时间和空间复杂度。在完成代码编写后,还需要进行测试验证,确保程序的正确性。 在解答题目过程,可以参考其他人的解题思路和代码实现,并进行对比和学习。LeetCode还提供了题目的讨论区,可以与其他的编程爱好者交流和分享经验。 总之,通过LeetCode可以提升自己的编程能力,加深对算法和数据结构的理解,并为面试和竞赛积累经验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值