678. Valid Parenthesis String

선택한 UI 언어에 맞게 문제 텍스트를 러시아어에서 번역합니다. 코드는 변경하지 않습니다.

Создайте карту, которая позволяет выполнять следующие действия:

Отображает строковый ключ на заданное значение.

returns сумму значений, у которых ключ имеет префикс, равный заданной строке.

Реализуйте класс MapSum:

Дана 문자열 s, содержащая только три типа символов: '(', ')' и '*'. Вернуть true, если s является допустимой.

Следующие правила определяют допустимую строку:

Любая открывающая скобка '(' должна иметь соответствующую закрывающую скобку ')'.

Любая закрывающая скобка ')' должна иметь соответствующую открывающую скобку '('.

Открывающая скобка '(' должна идти перед соответствующей закрывающей скобкой ')'.

'*' может рассматриваться как одна закрывающая скобка ')', одна открывающая скобка '(' или пустая 문자열 "".

예제:

Input: s = "()"

Output: true

Example 2:

C# 해법

매칭됨/원본
using System;
using System.Collections.Generic;
public class Solution {
    public bool CheckValidString(string s) {
        int n = s.Length;
        int[][] memo = new int[n][];
        for (int i = 0; i < n; i++) {
            memo[i] = new int[n];
            Array.Fill(memo[i], -1);
        }
        return IsValidString(0, 0, s, memo);
    }
    private bool IsValidString(int index, int openCount, string str, int[][] memo) {
        if (index == str.Length) {
            return openCount == 0;
        }
        if (memo[index][openCount] != -1) {
            return memo[index][openCount] == 1;
        }
        bool isValid = false;
        if (str[index] == '*') {
            isValid = IsValidString(index + 1, openCount + 1, str, memo);
            if (openCount > 0) {
                isValid = isValid || IsValidString(index + 1, openCount - 1, str, memo);
            }
            isValid = isValid || IsValidString(index + 1, openCount, str, memo);
        } else if (str[index] == '(') {
            isValid = IsValidString(index + 1, openCount + 1, str, memo);
        } else if (openCount > 0) {
            isValid = IsValidString(index + 1, openCount - 1, str, memo);
        }
        memo[index][openCount] = isValid ? 1 : 0;
        return isValid;
    }
}

C++ 해법

자동 초안, 제출 전 검토
#include <bits/stdc++.h>
using namespace std;

// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
    public bool CheckValidString(string s) {
        int n = s.size();
        int[][] memo = new int[n][];
        for (int i = 0; i < n; i++) {
            memo[i] = new int[n];
            Array.Fill(memo[i], -1);
        }
        return IsValidString(0, 0, s, memo);
    }
    private bool IsValidString(int index, int openCount, string str, int[][] memo) {
        if (index == str.size()) {
            return openCount == 0;
        }
        if (memo[index][openCount] != -1) {
            return memo[index][openCount] == 1;
        }
        bool isValid = false;
        if (str[index] == '*') {
            isValid = IsValidString(index + 1, openCount + 1, str, memo);
            if (openCount > 0) {
                isValid = isValid || IsValidString(index + 1, openCount - 1, str, memo);
            }
            isValid = isValid || IsValidString(index + 1, openCount, str, memo);
        } else if (str[index] == '(') {
            isValid = IsValidString(index + 1, openCount + 1, str, memo);
        } else if (openCount > 0) {
            isValid = IsValidString(index + 1, openCount - 1, str, memo);
        }
        memo[index][openCount] = isValid ? 1 : 0;
        return isValid;
    }
}

Java 해법

매칭됨/원본
import java.util.*;

class Solution {
    public boolean checkValidString(String s) {
        int n = s.length();
        int[][] memo = new int[n][n];
        for (int[] row : memo) Arrays.fill(row, -1);
        return isValidString(0, 0, s, memo);
    }
    
    private boolean isValidString(int index, int openCount, String str, int[][] memo) {
        if (index == str.length()) {
            return openCount == 0;
        }
        
        if (memo[index][openCount] != -1) {
            return memo[index][openCount] == 1;
        }
        
        boolean isValid = false;
        
        if (str.charAt(index) == '*') {
            isValid = isValidString(index + 1, openCount + 1, str, memo);
            if (openCount > 0) {
                isValid = isValid || isValidString(index + 1, openCount - 1, str, memo);
            }
            isValid = isValid || isValidString(index + 1, openCount, str, memo);
        } else if (str.charAt(index) == '(') {
            isValid = isValidString(index + 1, openCount + 1, str, memo);
        } else if (openCount > 0) {
            isValid = isValidString(index + 1, openCount - 1, str, memo);
        }
        
        memo[index][openCount] = isValid ? 1 : 0;
        return isValid;
    }
}

JavaScript 해법

매칭됨/원본
class Solution {
    checkValidString(s) {
        const memo = Array.from({ length: s.length }, () => Array(s.length).fill(-1));
        return this.isValidString(0, 0, s, memo);
    }
    
    isValidString(index, openCount, str, memo) {
        if (index === str.length) {
            return openCount === 0;
        }
        
        if (memo[index][openCount] !== -1) {
            return memo[index][openCount] === 1;
        }
        
        let isValid = false;
        
        if (str[index] === '*') {
            isValid = this.isValidString(index + 1, openCount + 1, str, memo);
            if (openCount > 0) {
                isValid = isValid || this.isValidString(index + 1, openCount - 1, str, memo);
            }
            isValid = isValid || this.isValidString(index + 1, openCount, str, memo);
        } else if (str[index] === '(') {
            isValid = this.isValidString(index + 1, openCount + 1, str, memo);
        } else if (openCount > 0) {
            isValid = this.isValidString(index + 1, openCount - 1, str, memo);
        }
        
        memo[index][openCount] = isValid ? 1 : 0;
        return isValid;
    }
}

Python 해법

매칭됨/원본
class Solution:
    def checkValidString(self, s: str) -> bool:
        memo = [[-1] * len(s) for _ in range(len(s))]
        return self.isValidString(0, 0, s, memo)

    def isValidString(self, index: int, openCount: int, s: str, memo: list) -> bool:
        if index == len(s):
            return openCount == 0

        if memo[index][openCount] != -1:
            return memo[index][openCount] == 1

        isValid = False

        if s[index] == '*':
            isValid = self.isValidString(index + 1, openCount + 1, s, memo)
            if openCount > 0:
                isValid = isValid or self.isValidString(index + 1, openCount - 1, s, memo)
            isValid = isValid or self.isValidString(index + 1, openCount, s, memo)
        elif s[index] == '(':
            isValid = self.isValidString(index + 1, openCount + 1, s, memo)
        elif openCount > 0:
            isValid = self.isValidString(index + 1, openCount - 1, s, memo)

        memo[index][openCount] = 1 if isValid else 0
        return isValid

Go 해법

매칭됨/원본
package main

type Solution struct {}

func (s *Solution) CheckValidString(str string) bool {
    memo := make([][]int, len(str))
    for i := range memo {
        memo[i] = make([]int, len(str))
        for j := range memo[i] {
            memo[i][j] = -1
        }
    }
    return s.isValidString(0, 0, str, memo)
}

func (s *Solution) isValidString(index, openCount int, str string, memo [][]int) bool {
    if index == len(str) {
        return openCount == 0
    }

    if memo[index][openCount] != -1 {
        return memo[index][openCount] == 1
    }

    isValid := false

    if str[index] == '*' {
        isValid = s.isValidString(index+1, openCount+1, str, memo) || // interpret as '('
                  s.isValidString(index+1, openCount, str, memo)   || // interpret as empty
                  (openCount > 0 && s.isValidString(index+1, openCount-1, str, memo)) // interpret as ')'
    } else if str[index] == '(' {
        isValid = s.isValidString(index+1, openCount+1, str, memo)
    } else { // ')'
        if openCount > 0 {
            isValid = s.isValidString(index+1, openCount-1, str, memo)
        }
    }

    memo[index][openCount] = 0
    if isValid {
        memo[index][openCount] = 1
    }
    return isValid
}

Algorithm

Инициализировать 2D вектор memo размером s.size() x s.size() - 1, представляющий неинициализированное состояние. Вызвать вспомогательную функцию isValidString с начальными параметрами index = 0, openCount = 0 и строкой s. Вернуть результат isValidString.

Вспомогательная функция isValidString. Базовый случай: если index достиг конца строки (index == s.size.), вернуть true, если openCount равен 0 (все скобки сбалансированы), и false в противном случае. Проверить, был ли результат для текущего index и openCount уже вычислен (мемоизирован) в memo. Если да, вернуть мемоизированный результат. Инициализировать isValid как false. Если текущий символ s[index] равен '*': Попробовать трактовать '*' как '(' и вызвать isValidString рекурсивно с index + 1 и openCount + 1. Если рекурсивный вызов вернет true, обновить isValid на true. Если openCount не равен нулю, попробовать трактовать '*' как ')' и вызвать isValidString рекурсивно с index + 1 и openCount - 1. Если рекурсивный вызов вернет true, обновить isValid на true. Попробовать трактовать '*' как пустой символ и вызвать isValidString рекурсивно с index + 1 и тем же openCount. Если рекурсивный вызов вернет true, обновить isValid на true.

Продолжение функции isValidString. Если текущий символ s[index] равен '(': Вызвать isValidString рекурсивно с index + 1 и openCount + 1. Обновить isValid с результатом рекурсивного вызова. Если текущий символ s[index] равен ')': Если openCount не равен нулю (есть открытые скобки), вызвать isValidString рекурсивно с index + 1 и openCount - 1. Обновить isValid с результатом рекурсивного вызова. Мемоизировать результат isValid в memo[index][openCount]. Вернуть isValid.

😎

Vacancies for this task

활성 채용 with overlapping task tags are 표시됨.

전체 채용
아직 활성 채용이 없습니다.