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

题目

给定 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类型
	}
}
  • 空间复杂度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;
	}
}
  • 空间复杂度O(1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HDU-五七小卡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值