Likou 844. Compare strings with backspace---two methods (stack and double pointer)

844. Compare strings with backspace

Given two strings of S and T, when they are input into a blank text editor, determine whether they are equal, and return the result. # Represents the backspace character.

Note: If you enter a backspace character for empty text, the text will remain empty.

Example 1:

Input: S = "ab#c", T = "ad#c"
Output: true
Explanation: Both S and T will become "ac".
Example 2:

Input: S = "ab##", T = "c#d#"
Output: true
Explanation: Both S and T will become "".
Example 3:

Input: S = "a##c", T = "#a#c"
Output: true
Explanation: Both S and T will become "c".
Example 4:

Input: S = "a#c", T = "b"
Output: false
Explanation: S will become "c", but T will still be "b".

提示:
1 <= S.length <= 200
1 <= T.length <= 200
S 和 T 只含有小写字母以及字符 '#'。
进阶:
你可以用 O(N) 的时间复杂度和 O(1) 的空间复杂度解决该问题吗?
 

answer:

Method one: stack + rebuild string

Due to the existence of the backspace key, we only need to use these backspace keys to reconstruct a real string. Finally, compare whether the two after reorganization are the same.

Code:

char*bj(char*str)//此为“重组”函数
{
    
    
    int n = strlen(str);
    char*temp=(char*)malloc((n+1)*sizeof(char));//用来临时储存“重组”后的字符串,先设置内存大点
    int len = 0;//此为代表“重组”后的字符串数组的下标,开始为0
    for(int i=0;i<n;i++)//for循环来填充
    {
    
    
        if(str[i]!='#')//如果不是退格键,则直接赋给他即可
        {
    
    
            temp[len]=str[i];
            len++;//下标先指向下一个
        }
        else if(len>0)//是退格键的情况,但前提须是“重组”后的字符串数组的下标须大于0
        	//因为进入此条件体内下面我们要对len--,所以len在进来时就必须先是>0的,不然会越界
        {
    
    
            len--;//因为是退格键,所以即相当于“删掉”了前一个,所以要对前一个进行重新赋值,所以下标往前一个
        }
    }
    temp[len]='\0';//因为开始不知道应该申请多大内存,而字符串数组以‘\0’为结尾
    			//所以先申请一个最大的,最后再“去掉”多余的即可
    return temp;
}
bool backspaceCompare(char * S, char * T){
    
    
    return strcmp(bj(S),bj(T))==0;//代入函数验证即可
}

This method is less efficient, but the logic is simpler.

Method 2: Logical processing-double pointer search

This method is very efficient, but logically more complicated.

The first thing to understand is that if you use a double pointer to search, the starting position should be searched from the beginning or from the end .
From the title, we can know that a character will only be affected by the backspace key that appears after it, and the backspace key that appears before it will not be affected . That is to say, if we search from the beginning, if we encounter #, we need to operate on the previous one. And if we search from the end, once we encounter #, we will save it first. When no # is encountered, we can immediately judge whether the character at this time will be deleted from the number of #s stored . For searching from scratch, we found that it is more complicated to complete this step.

Attach a picture of God’s solution to better understand the next process:
Insert picture description here

After confirming the search from the end, we can first search the S array. If the corresponding element is # at this time, store # once and move the pointer forward once; if it is not #, see if the stored # is offset If the offset is not completed, then offset once, and the pointer will move forward again; if the offset is completed, it means that the character at this time is equivalent to the real character that should exist after the backspace key processing, so you can use it at this time. Compare the characters obtained by the same operation with the T array to see if they are equal.

That is, the purpose of the above operation is to take out a real character after backspace processing from the S array and T array for comparison .

Here are some details of the code:

----Note: If i and j are both negative in the code, there is no need to compare whether S[i] and T[j] are equal, why?
Because when i and j are both negative, it means that they did not select the characters that actually existed after the backspace key operation. Since they are not selected , then it is fine.
Of course , it is also possible that both i and j have traversed their own arrays. , Then it’s okay, the traversal is complete and there is no need to compare it~

Note: Why is the condition of the while loop at the beginning "i>=0||j>=0"?
Because a pointer may be searched quickly because it is in a small array, the search is completed quickly, so at this time, its corresponding i or j is negative, but the other is slower and still searching. And this situation does not necessarily mean "true", nor does it necessarily mean "false" , so we need to perform another round of verification to see if the content is not searchable , if this is the case, it is "true" ; If this is not the case, that is , the content of one can still be searched when the other is searched , then the two must be different , so it is "false".

! ! ! ! And be clear ------i, j if it is not a negative value, it means that they have searched for the content, that is, the corresponding S[i], T[j] is not #. (this is caused by the while loop Conditions)

Code:

bool backspaceCompare(char * S, char * T){
    
    
    int i=strlen(S)-1;//S的指针
    int j=strlen(T)-1;//T的指针
    int nums = 0;//S的计数器,存储S的#个数
    int numt = 0;//T的计数器,存储T的#个数
    while(i>=0||j>=0)//进入搜索查找循环
    {
    
    
        while(i>=0)//先查找出S的经过退格处理的真正存在的字符,因为i为S的查找指针,
        	//每一个都要查找,所以i=0也要查找,所以循环为i>=0就要进入循环
        {
    
    
            if(S[i]=='#')
            {
    
    
                nums++;
                i--;
                continue;
            }
            if(nums!=0)
            {
    
    
                i--;
                nums--;
                continue;
            }
            if(nums==0)
            {
    
    
                break;
            }
        }
        while(j>=0)//再找出T的经过退格处理的真正存在的字符,同理j>=0
        {
    
    
            if(T[j]=='#')
            {
    
    
                numt++;
                j--;
                continue;
            }
            if(numt!=0)
            {
    
    
                j--;
                numt--;
                continue;
            }
            if(numt==0)
            {
    
    
                break;
            }
        }
        if(i>=0&&j>=0)//首先满足i,j不越界,即都搜索到了内容时
        {
    
    
            if(S[i]!=T[j])//进行比较
                return 0;
        }
        else//else的条件其实就是当不满足前面的if条件时,所以即i,j有越界的,即有没有搜索到内容的
        {
    
    
            if(i >= 0 || j >= 0)//在else的情况下,所以必定有至少一个没有搜索到内容
            {
    
    //若是都没搜索到,则没啥事,若是一个搜索到了,一个没搜索到,则一定为“假”了
                return false;//因为搜索时本来就把退格键使用了,所以此时显然S与T不相同了
            }
        }
        i--;//移动指针
        j--;
    }
    return 1;
}

Guess you like

Origin blog.csdn.net/xiangguang_fight/article/details/112291205