📜  支架平衡的最小互换

📅  最后修改于: 2021-10-26 06:07:33             🧑  作者: Mango

你得到一个由 N 个 ‘[‘ 方括号和 N 个 ‘]’ 方括号组成的 2N 个字符的字符串。如果字符串可以在 for S2[S1] 中表示,其中 S1 和 S2 是平衡字符串,则该字符串被认为是平衡的。我们可以通过交换相邻字符来使不平衡的字符串平衡。计算使字符串平衡所需的最小交换次数。

例子:

Input  : []][][
Output : 2
First swap: Position 3 and 4
[][]][
Second swap: Position 5 and 6
[][][]

Input  : [[][]]
Output : 0
The string is already balanced.

我们可以使用贪心策略来解决这个问题。如果前 X 个字符形成一个平衡字符串,我们可以忽略这些字符并继续。如果我们在所需的 ‘[‘ 之前遇到一个 ‘]’,那么我们必须开始交换元素以平衡字符串。

天真的方法
初始化 sum = 0,其中sum存储结果。遍历字符串,保持对遇到的“[”括号数量的计数。当我们遇到 ‘]’字符时减少这个计数。如果计数为负,那么我们必须开始平衡字符串。
让索引“i”代表我们所处的位置。我们现在前进到索引 j 处的下一个 ‘[‘。将总和增加 j – i。将位置 j 的 ‘[‘ 移动到位置 i,并将所有其他字符向右移动。将计数设置回 0 并继续遍历字符串。最后,’sum’ 将具有所需的值。

时间复杂度 = O(N^2)
额外空间 = O(1)

优化方法
我们可以首先遍历字符串并将“[”的位置存储在向量中,比如“ pos ”。将“p”初始化为 0。我们将使用 p 来遍历向量“pos”。与简单的方法类似,我们维护遇到的“[”括号的计数。当我们遇到'[‘时,我们增加计数并将’p’增加1。当我们遇到’]’时,我们减少计数。如果计数变为负数,这意味着我们必须开始交换。元素 pos[p] 告诉我们下一个 ‘[‘ 的索引。我们通过 pos[p] – i 增加总和,其中 i 是当前索引。我们可以交换当前索引和 pos[p] 中的元素并将计数重置为 0 并增加 p 以便它 pos[p] 指示下一个 ‘[‘。
由于我们已将原始方法中的 O(N) 步骤转换为 O(1) 步骤,因此我们新的时间复杂度降低了。

时间复杂度 = O(N)
额外空间 = O(N)

C++
// C++ program to count swaps required to balance string
#include 
#include 
#include 
using namespace std;
 
// Function to calculate swaps required
long swapCount(string s)
{
    // Keep track of '['
    vector pos;
    for (int i = 0; i < s.length(); ++i)
        if (s[i] == '[')
            pos.push_back(i);
 
    int count = 0; // To count number of encountered '['
    int p = 0;  // To track position of next '[' in pos
    long sum = 0; // To store result
 
    for (int i = 0; i < s.length(); ++i)
    {
        // Increment count and move p to next position
        if (s[i] == '[')
        {
            ++count;
            ++p;
        }
        else if (s[i] == ']')
            --count;
 
        // We have encountered an unbalanced part of string
        if (count < 0)
        {
            // Increment sum by number of swaps required
            // i.e. position of next '[' - current position
            sum += pos[p] - i;
            swap(s[i], s[pos[p]]);
            ++p;
 
            // Reset count to 1
            count = 1;
        }
    }
    return sum;
}
 
// Driver code
int main()
{
    string s = "[]][][";
    cout << swapCount(s) << "\n";
 
    s = "[[][]]";
    cout << swapCount(s) << "\n";
    return 0;
}


Java
// Java program to count swaps
// required to balance string
import java.util.*;
 
class GFG{
     
// Function to calculate swaps required
public static long swapCount(String s)
{
     
    // Keep track of '['
    Vector pos = new Vector();
    for(int i = 0; i < s.length(); ++i)
        if (s.charAt(i) == '[')
            pos.add(i);
             
    // To count number of encountered '['
    int count = 0;
     
    // To track position of next '[' in pos
    int p = 0; 
     
    // To store result
    long sum = 0;
     
    char[] S = s.toCharArray();
     
    for(int i = 0; i < s.length(); ++i)
    {
         
        // Increment count and move p
        // to next position
        if (S[i] == '[')
        {
            ++count;
            ++p;
        }
        else if (S[i] == ']')
            --count;
  
        // We have encountered an
        // unbalanced part of string
        if (count < 0)
        {
             
            // Increment sum by number of
            // swaps required i.e. position
            // of next '[' - current position
            sum += pos.get(p) - i;
            char temp = S[i];
            S[i] = S[pos.get(p)];
            S[pos.get(p)] = temp;
            ++p;
  
            // Reset count to 1
            count = 1;
        }
    }
    return sum;
}
 
// Driver code
public static void main(String[] args)
{
    String s = "[]][][";
    System.out.println(swapCount(s));
  
    s = "[[][]]";
    System.out.println(swapCount(s));
}
}
 
// This code is contributed by divyesh072019


Python3
# Python3 Program to count
# swaps required to balance
# string
 
# Function to calculate
# swaps required
def swapCount(s):
 
    # Keep track of '['
    pos = []
 
    for i in range(len(s)):
        if(s[i] == '['):
            pos.append(i)
 
    # To count number
    # of encountered '['        
    count = 0
     
    # To track position
    # of next '[' in pos
    p = 0   
     
    # To store result
    sum = 0       
    s = list(s)
     
    for i in range(len(s)):
 
        # Increment count and
        # move p to next position
        if(s[i] == '['):
            count += 1
            p += 1
        elif(s[i] == ']'):
            count -= 1
 
        # We have encountered an
        # unbalanced part of string
        if(count < 0):
           
            # Increment sum by number
            # of swaps required
            # i.e. position of next
            # '[' - current position
            sum += pos[p] - i
            s[i], s[pos[p]] = (s[pos[p]],
                               s[i])
            p += 1
 
            # Reset count to 1
            count = 1
    return sum
 
# Driver code
s = "[]][]["
print(swapCount(s))
 
s = "[[][]]"
print(swapCount(s))
 
# This code is contributed by avanitrachhadiya2155


C#
// C# program to count swaps
// required to balance string
using System.IO;
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG{
 
// Function to calculate swaps required
static long swapCount(string s)
{
     
    // Keep track of '['
    List pos = new List();
    for(int i = 0; i < s.Length; i++)
    {
        if (s[i] == '[')
        {
            pos.Add(i);
        }
    }
     
    // To count number of encountered '['
    int count = 0;
     
    // To track position of next '[' in pos
    int p = 0;
     
    // To store result
    long sum = 0;
     
    char[] S = s.ToCharArray();
     
    for(int i = 0; i < S.Length; i++)
    {
         
        // Increment count and move p
        // to next position
        if (S[i] == '[')
        {
            ++count;
            ++p;
        }
        else if (S[i] == ']')
        {
            --count;
        }
         
        // We have encountered an
        // unbalanced part of string
        if (count < 0)
        {
             
            // Increment sum by number of
            // swaps required i.e. position
            // of next '[' - current position
            sum += pos[p]-i;
            char temp = S[i];
            S[i] = S[pos[p]];
            S[pos[p]] = temp;
            ++p;
             
            // Reset count to 1
            count = 1;
        }
    }
    return sum;
}
 
// Driver code
static void Main()
{
    string s = "[]][][";
    Console.WriteLine(swapCount(s));
     
    s = "[[][]]";
    Console.WriteLine(swapCount(s));
}
}
 
// This code is contributed by rag2127


Javascript


C++
// C++ program to count swaps required
// to balance string
#include 
using namespace std;
 
long swapCount(string chars)
{
     
    // Stores total number of Left and
    // Right brackets encountered
    int countLeft = 0, countRight = 0;
     
    // swap stores the number of swaps
    // required imbalance maintains
    // the number of imbalance pair
    int swap = 0 , imbalance = 0;
      
    for(int i = 0; i < chars.length(); i++)
    {
        if (chars[i] == '[')
        {
             
            // Increment count of Left bracket
            countLeft++;
             
            if (imbalance > 0)
            {
                 
                // swaps count is last swap count + total
                // number imbalanced brackets
                swap += imbalance;
                 
                // imbalance decremented by 1 as it solved
                // only one imbalance of Left and Right
                imbalance--;    
            }
        }
        else if(chars[i] == ']' )
        {
             
            // Increment count of Right bracket
            countRight++;
             
            // imbalance is reset to current difference
            // between Left and Right brackets
            imbalance = (countRight - countLeft);
        }
    }
    return swap;
}
 
// Driver code 
int main()
{
    string s = "[]][][";
    cout << swapCount(s) << endl;
 
    s = "[[][]]";
    cout << swapCount(s) << endl;
 
    return 0;
}
 
// This code is contributed by divyeshrabadiya07


Java
// Java Program to count swaps required to balance string
public class BalanceParan
{
     
    static long swapCount(String s)
    {
        char[] chars = s.toCharArray();
         
        // stores total number of Left and Right
        // brackets encountered
        int countLeft = 0, countRight = 0;
                // swap stores the number of swaps required
        //imbalance maintains the number of imbalance pair
        int swap = 0 , imbalance = 0;
         
        for(int i =0; i< chars.length; i++)
        {
            if(chars[i] == '[')
            {
                // increment count of Left bracket
                countLeft++;
                if(imbalance > 0)
                {
                    // swaps count is last swap count + total
                    // number imbalanced brackets
                    swap += imbalance;
                    // imbalance decremented by 1 as it solved
                    // only one imbalance of Left and Right
                    imbalance--;    
                }
            } else if(chars[i] == ']' )
            {
                // increment count of Right bracket
                countRight++;
                // imbalance is reset to current difference
                // between Left and Right brackets
                imbalance = (countRight-countLeft);
            }
        }
        return swap;
    }
 
// Driver code
    public static void main(String args[])
    {
        String s = "[]][][";
        System.out.println(swapCount(s) );
 
        s = "[[][]]";
        System.out.println(swapCount(s) );
         
    }
}
// This code is contributed by Janmejaya Das.


Python3
# Python3 program to count swaps required to
# balance string
def swapCount(s):
     
    chars = s
     
    # Stores total number of left and 
    # right brackets encountered
    countLeft = 0
    countRight = 0
     
    # Swap stores the number of swaps 
    # required imbalance maintains the
    # number of imbalance pair
    swap = 0
    imbalance = 0;
     
    for i in range(len(chars)):
        if chars[i] == '[':
             
            # Increment count of left bracket
            countLeft += 1
             
            if imbalance > 0:
                 
                # Swaps count is last swap
                # count + total number
                # imbalanced brackets
                swap += imbalance
                 
                # Imbalance decremented by 1
                # as it solved only one
                # imbalance of left and right
                imbalance -= 1
                 
        elif chars[i] == ']':
             
            # Increment count of right bracket
            countRight += 1
             
            # Imbalance is reset to current
            # difference between left and
            # right brackets
            imbalance = (countRight - countLeft)
 
    return swap
 
# Driver code
s = "[]][][";
print(swapCount(s))
 
s = "[[][]]";
print(swapCount(s))
 
# This code is contributed by Prateek Gupta


C#
// C# Program to count swaps required
// to balance string
using System;
 
class GFG
{
 
public static long swapCount(string s)
{
    char[] chars = s.ToCharArray();
 
    // stores the total number of Left and
    // Right brackets encountered
    int countLeft = 0, countRight = 0;
     
    // swap stores the number of swaps
    // required imbalance maintains the
    // number of imbalance pair
    int swap = 0, imbalance = 0;
 
    for (int i = 0; i < chars.Length; i++)
    {
        if (chars[i] == '[')
        {
            // increment count of Left bracket
            countLeft++;
            if (imbalance > 0)
            {
                // swaps count is last swap count + total
                // number imbalanced brackets
                swap += imbalance;
                 
                // imbalance decremented by 1 as it solved
                // only one imbalance of Left and Right
                imbalance--;
            }
        }
        else if (chars[i] == ']')
        {
            // increment count of Right bracket
            countRight++;
             
            // imbalance is reset to current difference
            // between Left and Right brackets
            imbalance = (countRight - countLeft);
        }
    }
    return swap;
}
 
// Driver code
public static void Main(string[] args)
{
    string s = "[]][][";
    Console.WriteLine(swapCount(s));
 
    s = "[[][]]";
    Console.WriteLine(swapCount(s));
}
}
 
// This code is contributed by Shrikant13


Javascript


输出:

2
0

另一种方法:
时间复杂度 = O(N)
额外空间 = O(1)
我们可以不必存储'[‘的位置。

下面是实现:

C++

// C++ program to count swaps required
// to balance string
#include 
using namespace std;
 
long swapCount(string chars)
{
     
    // Stores total number of Left and
    // Right brackets encountered
    int countLeft = 0, countRight = 0;
     
    // swap stores the number of swaps
    // required imbalance maintains
    // the number of imbalance pair
    int swap = 0 , imbalance = 0;
      
    for(int i = 0; i < chars.length(); i++)
    {
        if (chars[i] == '[')
        {
             
            // Increment count of Left bracket
            countLeft++;
             
            if (imbalance > 0)
            {
                 
                // swaps count is last swap count + total
                // number imbalanced brackets
                swap += imbalance;
                 
                // imbalance decremented by 1 as it solved
                // only one imbalance of Left and Right
                imbalance--;    
            }
        }
        else if(chars[i] == ']' )
        {
             
            // Increment count of Right bracket
            countRight++;
             
            // imbalance is reset to current difference
            // between Left and Right brackets
            imbalance = (countRight - countLeft);
        }
    }
    return swap;
}
 
// Driver code 
int main()
{
    string s = "[]][][";
    cout << swapCount(s) << endl;
 
    s = "[[][]]";
    cout << swapCount(s) << endl;
 
    return 0;
}
 
// This code is contributed by divyeshrabadiya07

Java

// Java Program to count swaps required to balance string
public class BalanceParan
{
     
    static long swapCount(String s)
    {
        char[] chars = s.toCharArray();
         
        // stores total number of Left and Right
        // brackets encountered
        int countLeft = 0, countRight = 0;
                // swap stores the number of swaps required
        //imbalance maintains the number of imbalance pair
        int swap = 0 , imbalance = 0;
         
        for(int i =0; i< chars.length; i++)
        {
            if(chars[i] == '[')
            {
                // increment count of Left bracket
                countLeft++;
                if(imbalance > 0)
                {
                    // swaps count is last swap count + total
                    // number imbalanced brackets
                    swap += imbalance;
                    // imbalance decremented by 1 as it solved
                    // only one imbalance of Left and Right
                    imbalance--;    
                }
            } else if(chars[i] == ']' )
            {
                // increment count of Right bracket
                countRight++;
                // imbalance is reset to current difference
                // between Left and Right brackets
                imbalance = (countRight-countLeft);
            }
        }
        return swap;
    }
 
// Driver code
    public static void main(String args[])
    {
        String s = "[]][][";
        System.out.println(swapCount(s) );
 
        s = "[[][]]";
        System.out.println(swapCount(s) );
         
    }
}
// This code is contributed by Janmejaya Das.

蟒蛇3

# Python3 program to count swaps required to
# balance string
def swapCount(s):
     
    chars = s
     
    # Stores total number of left and 
    # right brackets encountered
    countLeft = 0
    countRight = 0
     
    # Swap stores the number of swaps 
    # required imbalance maintains the
    # number of imbalance pair
    swap = 0
    imbalance = 0;
     
    for i in range(len(chars)):
        if chars[i] == '[':
             
            # Increment count of left bracket
            countLeft += 1
             
            if imbalance > 0:
                 
                # Swaps count is last swap
                # count + total number
                # imbalanced brackets
                swap += imbalance
                 
                # Imbalance decremented by 1
                # as it solved only one
                # imbalance of left and right
                imbalance -= 1
                 
        elif chars[i] == ']':
             
            # Increment count of right bracket
            countRight += 1
             
            # Imbalance is reset to current
            # difference between left and
            # right brackets
            imbalance = (countRight - countLeft)
 
    return swap
 
# Driver code
s = "[]][][";
print(swapCount(s))
 
s = "[[][]]";
print(swapCount(s))
 
# This code is contributed by Prateek Gupta

C#

// C# Program to count swaps required
// to balance string
using System;
 
class GFG
{
 
public static long swapCount(string s)
{
    char[] chars = s.ToCharArray();
 
    // stores the total number of Left and
    // Right brackets encountered
    int countLeft = 0, countRight = 0;
     
    // swap stores the number of swaps
    // required imbalance maintains the
    // number of imbalance pair
    int swap = 0, imbalance = 0;
 
    for (int i = 0; i < chars.Length; i++)
    {
        if (chars[i] == '[')
        {
            // increment count of Left bracket
            countLeft++;
            if (imbalance > 0)
            {
                // swaps count is last swap count + total
                // number imbalanced brackets
                swap += imbalance;
                 
                // imbalance decremented by 1 as it solved
                // only one imbalance of Left and Right
                imbalance--;
            }
        }
        else if (chars[i] == ']')
        {
            // increment count of Right bracket
            countRight++;
             
            // imbalance is reset to current difference
            // between Left and Right brackets
            imbalance = (countRight - countLeft);
        }
    }
    return swap;
}
 
// Driver code
public static void Main(string[] args)
{
    string s = "[]][][";
    Console.WriteLine(swapCount(s));
 
    s = "[[][]]";
    Console.WriteLine(swapCount(s));
}
}
 
// This code is contributed by Shrikant13

Javascript


输出:

2
0

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程