Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

ลบวงเล็บน้อยที่สุดเพื่อให้ถูกต้อง (Minimum Remove to Make Valid Parentheses) ใน C++


โจทย์: กำหนดสตริง s ประกอบด้วย '(', ')' และตัวอักษรภาษาอังกฤษพิมพ์เล็ก ต้อง ลบวงเล็บน้อยที่สุด ( '(' หรือ ')' ในตำแหน่งไหนก็ได้) เพื่อให้สตริงวงเล็บที่ได้เป็น valid และคืนค่าสตริงที่ถูกต้องใดๆหนึ่ง

สตริงวงเล็บถูกต้อง (valid) เมื่อ:

  • เป็นสตริงว่าง หรือมีแต่ตัวอักษรพิมพ์เล็ก
  • เขียนในรูป AB (A ต่อ B) โดย A และ B เป็น valid strings
  • เขียนในรูป (A) โดย A เป็น valid string

ตัวอย่าง

Input: "a)b(c)d"
Output: "ab(c)d"

แนวทางแก้ปัญหา (ใช้ Stack)

  1. สร้าง stack st เก็บ index ของ '('
  2. วนลูปทุกตัวอักษรใน s:
    • ถ้าเป็น '(' : push index เข้า stack
    • ถ้าเป็น ')' : ถ้า stack ไม่ว่าง pop ออก, มิฉะนั้นทำเครื่องหมาย s[i] = '*' (จะลบภายหลัง)
  3. หลังวนลูป: index ที่เหลือใน stack คือ '(' ที่ไม่มีคู่ ทำเครื่องหมาย '*' ทุกตัว
  4. สร้างสตริงคำตอบโดยข้ามตัวอักษร '*'

ตัวอย่างโค้ดเต็ม

#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
    string minRemoveToMakeValid(string s) {
        stack<int> st;
        for(int i = 0; i < s.size(); i++) {
            if(s[i] == '(') st.push(i);
            else if(s[i] == ')') {
                if(!st.empty()) st.pop();
                else s[i] = '*'; // mark for removal
            }
        }
        while(!st.empty()) {
            s[st.top()] = '*';
            st.pop();
        }
        string ans = "";
        for(int i = 0; i < s.size(); i++) {
            if(s[i] != '*') ans += s[i];
        }
        return ans;
    }
};

int main() {
    Solution ob;
    cout << (ob.minRemoveToMakeValid("a)b(c)d"));
}

Input

"a)b(c)d"

Output

ab(c)d