591. Tag Validator

Difficulty:
Related Topics:
Similar Questions:

Problem

Given a string representing a code snippet, implement a tag validator to parse the code and return whether it is valid.

A code snippet is valid if all the following rules hold:

  Example 1:

Input: code = "This is the first line ]]>"
Output: true
Explanation: 
The code is wrapped in a closed tag :  and . 
The TAG_NAME is valid, the TAG_CONTENT consists of some characters and cdata. 
Although CDATA_CONTENT has an unmatched start tag with invalid TAG_NAME, it should be considered as plain text, not parsed as a tag.
So TAG_CONTENT is valid, and then the code is valid. Thus return true.

Example 2:

Input: code = ">>  ![cdata[]] ]>]]>]]>>]"
Output: true
Explanation:
We first separate the code into : start_tag|tag_content|end_tag.
start_tag -> ""
end_tag -> ""
tag_content could also be separated into : text1|cdata|text2.
text1 -> ">>  ![cdata[]] "
cdata -> "]>]]>", where the CDATA_CONTENT is "]>"
text2 -> "]]>>]"
The reason why start_tag is NOT ">>" is because of the rule 6.
The reason why cdata is NOT "]>]]>]]>" is because of the rule 7.

Example 3:

Input: code = "  **    **"
Output: false
Explanation: Unbalanced. If "" is closed, then "" must be unmatched, and vice versa.

  Constraints:

Solution

class Solution {
    public boolean isValid(String code) {
        Stack<String> stack = new Stack<>();
        for(int i = 0; i < code.length();){
            if(i>0 && stack.isEmpty()) return false;
            if(code.startsWith("<![CDATA[", i)){
                int j = i+9;
                i = code.indexOf("]]>", j);
                if(i < 0) return false;
                i += 3;
            }else if(code.startsWith("</", i)){
                int j = i + 2;
                i = code.indexOf('>', j);
                if(i < 0 || i == j || i - j > 9) return false;
                for(int k = j; k < i; k++){
                    if(!Character.isUpperCase(code.charAt(k))) return false;
                }
                String s = code.substring(j, i++);
                if(stack.isEmpty() || !stack.pop().equals(s)) return false;
            }else if(code.startsWith("<", i)){
                int j = i + 1;
                i = code.indexOf('>', j);
                if(i < 0 || i == j || i - j > 9) return false;
                for(int k = j; k < i; k++){
                    if(!Character.isUpperCase(code.charAt(k))) return false;
                }
                String s = code.substring(j, i++);
                stack.push(s);
            }else{
                i++;
            }
        }
        return stack.isEmpty();
    }
}

Explain:

nope.

Complexity: