[Daily Scratching Algorithm Question (2)] Compressed strings | Can two strings be equal by performing only one string swap?


1. Compressed string

click me directly~

insert image description here

train of thought

Use the double pointer method

The general process is as follows:

  • Use double pointers to read (read) and write (write) pointers respectively. The read pointer keeps going backwards. When the read pointer reaches the last position, or when the next position of read and read is not equal to the current position, it means that the The read pointer has reached the last position of a string of identical substrings.
  • At this time, the write pointer starts to record specific characters, and a left pointer is given to record the current position. At this time, the length of each substring isread - left +1
  • Use short division to record the length of the substring, and then reverse it.

The specific operation is as follows:

  • 1. Given two pointers write and left (left指针记录每一个子串的开始位置), respectively point to the position of the first element.
  • 2. Use the read pointer to traverse the string. When read encounters a character that is not equal to the current character, or read reaches the end, then write the pointer to record the character and length of the current substring, then let write Walk backward while recording.
  • 3. When the write pointer starts to record the length of the substring, give a subscript begin. This begin is the starting position for recording the length of the substring. For example, the length of a string is: 123. What needs to be recorded in the chars array is ["1 ", "2", "3"], begin records the position of the "1" subscript.
  • 4. Use short division to record each digit of the length of a certain string, and then invert it. The beginning of the inversion is begin, and the end is write.
  • 5. Because write always goes backwards, until all the characters and the length of each identical string are recorded, then the length of write can be finally returned

The specific code is as follows:

class Solution {
    
    
public:
    int compress(vector<char>& chars) 
    {
    
    
        int write = 0,left = 0;
        for(int read = 0;read<chars.size();++read)
        {
    
    
            if(read == chars.size()-1 ||
             chars[read]!=chars[read+1])
            {
    
       
                chars[write++] = chars[read];//存储字符
                int begin = write; // 逆置的左下标
                
                int n = read - left + 1 ; 
                if(n>1)
                {
    
    
                    while(n)
                    {
    
    
                        chars[write++] = (n%10) + '0';
                        n/=10;
                    }
                    //逆置的右下标是write
                    reverse(&chars[begin],&chars[write]);
                }
                left = read+1;
            }
        }
        return write;
    }
};

时间复杂度:O(n),空间复杂度O(1)

2. Can two strings be equal by performing only one string swap

click me directly~

insert image description here

Idea 1: counting method

  • Case 1: If the lengths of the two strings are different, then no matter how they are exchanged, they must be unequal, and return false
  • Case 2: If both strings have the same length:
    • Case 1: If there are more than two characters that are not the same, or there is only one character that is not the same, then the two strings must be unequal no matter how the characters are exchanged, and return false
    • Situation 2: If there are exactly two different characters, there are two ways to solve it:
      • 1. Exchange the positions of these two characters that are not the same, if s1 == s2 after the exchange, return true, otherwise false.
      • 2. Judging whether s1[i] == s2[j], s1[j] == s2[i] is satisfied.

Please see the following code for details:

class Solution {
    
    
public:
    bool areAlmostEqual(string s1, string s2)
    {
    
    
        //1.相等,true
        if(s1 == s2)
            return true;
        //2.长度不等,false
        if(s1.size() != s2.size())
            return false;
        
        //3.遍历s1和s2,如果发现有两个以上字母不同,不管怎么交换都不等       
        vector<int> v1; // 两个下标
        int count = 0;//计算s1和s2有几个不等的字母
        for(int i = 0;i<s1.size();++i)
        {
    
    
            if(s1[i]!=s2[i])
            {
    
    
                ++count;
                v1.push_back(i);
            }
        }

        //如果不是只有两个字母不同,不管怎么交换一定不等。
        if(count !=2)
            return false;

        return s1[v1[0]] == s2[v1[1]] && 
        s1[v1[1]] == s2[v1[0]] ;

        //下面的操作也可
         //swap(s2[v1[0]],s2[v1[1]]);
        // if(s1 == s2)
        //     return true;

        // return false;
    }
};

Idea 2: Simulation method

The overall idea of ​​the simulation method is roughly the same as that of the counting method.
Given two initial values ​​pos1 and pos2 are both -1, record the subscripts of characters with different characters in the two strings.

  • If there are more than two or only one different positions, return false
  • If there are two different positions or no different positions, return true

Please see the following code for details:

class Solution {
    
    
public:
    bool areAlmostEqual(string s1, string s2)
    {
    
    
        int n = s1.size(),pos1 = -1,pos2 = -1;
        for(int i = 0;i<n;++i)
        {
    
    
            if(s1[i] == s2[i])
                continue;

            if(pos1 == -1)
                pos1 = i;
            else if(pos2 == -1)
                pos2 = i;
            
            //该情况是超过两个不同的字符
            else
                return false;
        }

            //该情况是没有不同的字符
        if(pos1 == -1)
            return true;
            //该情况是只有一个不同的字符
        if(pos2 == -1)
            return false;
        
            //该情况是正常情况
        return s1[pos1] == s2[pos2] && s1[pos2] == s2[pos1];
    }
};

Summarize

By writing today's two questions, I re-recognized the power of the double-pointer method, and I can consider the double-pointer method everywhere.

For example: sorting, string inversion, string compression, etc., you can consider the double pointer method for questions about strings,
and as long as two characters in two strings are involved, you can simulate subscripts , or counting method to achieve.

Guess you like

Origin blog.csdn.net/w2915w/article/details/131090297