• 代码随想录——比较含退格的字符串


    题目

    给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果。 # 代表退格字符。

    注意:如果对空文本输入退格字符,文本继续为空。

    示例 1:

    输入:S = “ab#c”, T = “ad#c” 输出:true 解释:S 和 T 都会变成 “ac”。 示例 2:

    输入:S = “ab##”, T = “c#d#” 输出:true 解释:S 和 T 都会变成 “”。 示例 3:

    输入:S = “a##c”, T = “#a#c” 输出:true 解释:S 和 T 都会变成 “c”。 示例 4:

    输入:S = “a#c”, T = “b” 输出:false 解释:S 会变成 “c”,但 T 仍然是 “b”

    思路

    方法一:重构字符串(栈的思想)

    • 如果遇到退格符,则弹出栈顶元素
    • 如果是普通字符,则入栈

    java代码如下:

    class Solution {
    	public boolean backspaceCompare(String s, String t){
    		StringBuilder sb1 = new StringBuilder();//模拟栈
    		StringBuilder sb2 = new StringBuilder();//模拟栈
    		//分别处理两个String
    		for(char c : s.toCharArray()){//将字符串s转化成字符数组,并遍历每一个字符
    			if(c != '#'){
    				sb1.append(c);//模拟入栈
    			} else if (sb1.length() > 0){//如果是退格符,则弹出栈顶元素,同时并且要非空
    				sb1.deleteCharAt(sb1.length() - 1);//模拟弹栈,栈顶元素相当于字符串的最后一个字符
    			}
    		}
    		for(char c : t.toCharArray()){
    			if(c != '#'){
    				sb2.append(c);
    			} else if (sb2.length() > 0){
    				sb2.deleteCharAt(sb2.length() - 1);
    			}
    		}
    		return sb1.toString().equals(sb2.toString());//将StringBuilder转化成String类型
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 空间复杂度O(n)

    方法二:双指针法

    一个字符是否会被删掉,只取决于该字符后面的退格符,而与该字符前面的退格符无关

    因此可以逆序地遍历字符串,就可以立即确定当前字符是否会被删掉

    这里定义skip表示当前要删除的字符的数量,每遍历到一个字符

    • 如果字符是退格符,则skip++,表示要删除一个字符
    • 如果字符是普通字符:
      (1)若skip == 0,则当前字符不需要删除
      (2)若skip!= 0,则当前字符要删除,skip--

    然后定义两个指针,分别指向两字符串的末尾;每次让两指针逆序地遍历两字符串,直到两字符串能够各自确定一个字符,然后将这两个字符进行比较;重复这一过程直到找到的两个字符不相等,或遍历完字符串为止。

    java代码如下:

    class Solution {
    	public boolean backspaceCompare(String s, String t){
    		int i = s.length() - 1;
    		int j = t.length() - 1 ;
    		int skipS = 0, skipT = 0;//记录S和T的#数量
    		while(i >= 0 || j >= 0){
    			while(i >= 0){
    				if(s.charAt(i) == '#'){//如果是退格符
    					skipS++;
    					i--;
    				} else if (skipS > 0){//如果是普通字符,并且需要删除
    					skipS--;
    					i--;
    				} else {
    					break;//以上条件均不满足的话,表示找一个不需要删除的字符,即一个可供比较的字符
    				}
    			}
    			while(j >= 0){
    				if(t.charAt(j) == '#'){
    					skipT++;
    					j--;
    				} else if (skipT > 0){
    					skipT--;
    					j--;
    				} else{
    					break;
    				}
    			}
    			//都找到了可比较的字符之后,开始比较
    			if(i >= 0 && j >= 0){//如果二者都没遍历完
    				if(s.charAt(i) != t.charAt(j)){//并且字符不相等的话
    					return false;
    				}
    			} else if(i >= 0 || j >= 0){//如果二者有一个遍历完了
    				return false;				
    			}
    			i--;
    			j--;
    		}
    		return true;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 空间复杂度O(1)
  • 相关阅读:
    [C++数据结构](33)图,图的遍历,最小生成树,最短路径算法详解
    工作几年,如何快速晋升至架构师?
    Rust和Pytho写一段采集公众号代码
    【论文阅读】ART-SLAM: Accurate Real-Time 6DoF LiDAR SLAM
    跨境人,是继续坚守还是求新变新?(Starday)
    一文熟悉 Go 的循环结构 —— for 循环
    NumPy入门文档
    spring 5.2+ http返回结果json格式字符集丢失问题
    02-Go语言基础变量和常量
    pandas写入MySQL
  • 原文地址:https://blog.csdn.net/qq_39473176/article/details/127808925