[Illustration] remember once Shredded algorithm interview: the interviewer to four bytes beat me batter

Byte beating the company, should be all autumn recruit companies, one of the most important algorithms, and each interview will let you Shredded basic algorithm, this article today on the record at the time asked several algorithms questions, and each algorithm problem I have detailed the given optimal solution , reproduced below at the time of the interview scene. Reading will let you gain something

A calf try knife: Effective brackets

In most cases, the interviewer will ask a very difficult question, but you do not be too happy, because this question can often develop a more difficult question, or a question may seem simple, but given the optimal solution is indeed not easy. This question is this

Includes only a given '(', ')' of the string, the string is determined whether or not valid. Note: the empty string belongs to a valid string

示例 1:
输入: "(())"
输出: true
  
 实例 2:
 输入: "())("
输出: false
 

At first glance this question, I went, so simple, stable (because one side when the interviewer has just been too hate Dragon Quest of the DP title in leetcdoe belong to hard level).

In fact, this question of leetcode question 20 of the simplified version , is easy level

So I unthinkingly directly stack to solve, and 99% believe it will work out with a stack? Here I say a little bar following procedure, follow these steps:

1, as they traverse the string is encountered "(" let it stack encounter ")" it is determined that there is no next stack "(":

(1)、如果有,则把处于栈顶的 "("  弹出,相当于和 ")" 进行匹配,然后继续往后遍历字符串

(2)、如果没有,则匹配失败。相当于字符串的最前面出现了 ")",显然这是不合理的。

2, when the character string is completed traversed, it is determined whether the stack is empty, if empty string indicates valid or invalid.

In order to take into account white , I give you drew a diagram illustrates ,,,, my conscience too.

Here Insert Picture Description

Code shown below (Java, Java can learn but not read)

public static boolean isValid(String s){
    if(s == null || s.length() < 1)
        return true;
    int n = s.length();// 字符串长度
    // 创建一个栈来装字符
    Stack<Character> stack = new Stack<>();
    // 遍历字符串
    for(int i = 0; i < n; i++){
        // 获取字符串的第 i 个字符
        char c = s.charAt(i);
        if(c == '('){
            stack.push(c);
        }else{
            if(stack.isEmpty())
                return false;
            else
                stack.pop();
        }
    }
    // 判断是否为空
    if(stack.isEmpty())
        return true;
    
    return false;
}

Second, optimization

Then the interviewer asks me this question of space complexity is O (n), asked if I could optimize it?

To be honest, if you have done the first 20 questions leetcode, it may be your mind will be directed not necessarily, because that question is to deal with a stack of the optimal solution. But this question belongs to a simplified version, in fact, can optimize the space complexity to O (1), we can think about, oh.

Since we stack inside the store are the same character "(" In fact, we can use a variable to replace the stack, this variable record number "(" encountered "(" variable is incremented encountered " ) "variables minus 1, the value of the stack is empty is equivalent to 0 variable.

At that time I do not know why my mind a little, pretty soon this method, so a minute to modify the good code, as follows:

public static boolean isValid(String s){
    if(s == null || s.length() < 1)
        return true;
    int n = s.length();// 字符串长度
    // 用来记录遇到的 "(" 的个数
    int sum = 0;
    // 遍历字符串
    for(int i = 0; i < n; i++){
        // 获取字符串的第 i 个字符
        char c = s.charAt(i);
        if(c == '('){
            sum++;
        }else{
            if(sum == 0)
                return false;
            else
                sum--;
        }
    }
    return sum == 0 ? true : false;
}

This way, then, the time complexity is O (n), the spatial complexity is O (1).

Third, the maximum validity brackets

Then the interviewer will continue to continue to increase the difficulty of this question, the question read as follows

Given a string containing only '(' and ''), find the length of the longest substring comprising an effective parentheses.

示例 1:

输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"
示例 2:

输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"

In fact, this question is leetcode of the original title, the first 32 questions, the difficulty is hard.

This question is because I have done before, smiled, pretending to think about with a serious expression, then immediately gives the idea, I just started using violence law is.

1. Violence Act

Violence is actually very simple, that is the beginning of the first character as the first character of the longest effective parentheses to traverse the string, then the second character as the first character of the longest effective parentheses to traverse the string, then the third characters ......

For example, s = "()) (())".

The first character as the first character, then max = 2 (third encounter characters ')' will not match up)
the second character as the first character, then max = 0 (beginning ')', apparently what can not match)
the third character as the first character, max = 0 is
the fourth character as the first character, then. 4 = max
.....
time complexity of this approach is O (n ^ 2) space complexity is O (1)

The basic questions, like those above, but do n traversal.

Then the interviewer asked, but also optimize it?

Knew would ask optimized, and before I did myself this question, so pretend to think for a moment, immediately gives the optimization.

2, optimization

This question optimized version we still do use the stack, but the stack of time, not to let "(" stack, but let "(" subscript stack as follows:

1, -1 into the first stack. (As for why? See behind you to know)
2 ,, for each encounter '(' we will its index into the stack.
3, for each encounter ')', we pop Zhanding elements and the current element index subscript under the pop-up element as a difference , obtained length brackets currently valid string .

In this way, we continue to calculate the effective length of the substring, and eventually return to the longest effective length of the substring.

can not read it? Right, get me the example of FIG draw several, for example s = "()) (())", and with the variable max to hold the degree of the longest string of effective, i denotes index of the current string

0, Initialization: max = 0; i = 0. -1 into the stack
Here Insert Picture Description

1, i = 0, s [i] = '(', subscript i = 0 Drawing
Here Insert Picture Description

2、i = 1,s[i] = ')',出栈; i - 栈顶元素 = 1 - (-1) = 2,此时 max = 2
Here Insert Picture Description
3、i = 2,s[i] = ')',出栈;这个时候要注意:由于 -1 出栈后,栈顶没有元素了,所以这个时候我们必须把 ')' 的下标入栈,相当于最开始的初始化。
Here Insert Picture Description
4、i = 3,s[i] = '(',入栈;
Here Insert Picture Description
5、i = 4,s[i] = '(',入栈;
Here Insert Picture Description
6、i = 5,s[i] = ')',出栈;i - 栈顶 = 5 - 3 = 2;此时 max = 2;
Here Insert Picture Description
7、i = 6,s[i] = ')',出栈;i - 栈顶 = 6 - 2 = 4;此时 max = 4;
Here Insert Picture Description
8、遍历结束,最长有效括号为 4。

看不大懂?没事,看下代码加深理解勒,代码如下:

public int longestValidParentheses(String s) {
    int max = 0;
    Stack<Integer> stack = new Stack<>();
    stack.push(-1);
    for (int i = 0; i < s.length(); i++) {
        if (s.charAt(i) == '(') {
        //下标入栈
            stack.push(i);
        } else {
        // 出栈
            stack.pop();
            // 看栈顶是否为空,为空的话就不能作差了
            if (stack.empty()) {
                stack.push(i);
            } else {
            // i - 栈顶,获得档期有效括号长度
                max = Math.max(max, i - stack.peek());
            }
        }
    }
    return maxans;
}

这种做法的时间复杂度为 O(n),空间复杂度为 O(n),能想到用栈来处理,算是很不错的了。

4、最后一击

我以为我给出这个解法算是可以的了,面试官应该换一道题的了,然后,面试官又来了一句:还能再优化吗?。这个时候我陷入了沉思.......

看文章的各位大佬们可以想一想在空间上是否还能优化,因为在时间上是不可能优化的了。

想了一会,居然不可以用栈,优化的方案肯定是类似于上面那道题一样,用记录数量的变量来代替栈,然后就被我想出了,具体如下:

实际上,这道题仍然可以像上面那样,用变量来代替栈来优化,不过这个时候我们需要两个变量,我们假设变量为 left 和 right。

我们在从从左到右遍历字符串的过程中,用 left 记录 '(' 的数量,用 right 记录 ')' 的数量。并且在遍历的过程中:

1、如果 left == right,显然这个时候 right 个 ')' 都将一定能够得到匹配。所以当前的有效括号长度为 2 * right。然后更新 max。

2、如果 left < right,显然这个时候部分 ')' 一定得不到匹配,此时我们把 left 和 right 都置为 0。

当遍历完字符串,我们是否就得到最大长度的有效括号了呢?大家可以想一下

答是不可以的,我们还需要从右到左遍历计算一下。

为什么呢?

因为实际上 '(' 和 ')' 其实是等价的,为什么就不可以倒过来遍历计算呢?所以,千万别忽略了哈。

最后的代码如下:

public int longestValidParentheses(String s) {
    if(s == null || s.length() < 1)
        return 0;
    int left = 0, right = 0, max = 0;
    // 从左到右
    for (int i = 0; i < s.length(); i++) {
        if (s.charAt(i) == '(') {
            left++;
        } else {
            right++;
        }
        if (left == right) {
            max = Math.max(max, 2 * right);
        } else if(right > left){
            left = right = 0;
        }
    }
    left = right = 0;
    // 从右到左
    for (int i = s.length() - 1; i >= 0; i--) {
        if (s.charAt(i) == '(') {
            left++;
        } else {
            right++;
        }
        if (left == right) {
            max = Math.max(max, 2 * left);
        } else if (left > right) {
            left = right = 0;
        }
    }
    return max;
}

这种做法的时间复杂度为 O(n),空间复杂度为 O(1)。

总结

说时候,最后一种方法还是比较难想到了,从这次面试中也可以看出,千万不要看一道题很简单,有些题要做出来很简单,但是,如果要以最优解的方式做出来,难度马上指数上升。。

如果你后面看不大懂,建议多看几遍哦,这道题考的频率还是挺高的,主要是可以做的方法多,每种方法的效率又不一样,不过我这里必须给你们的提醒,就是平时在做题的时候,一定要寻找最优解,而不是 ac 了就不管了,应该多看看别人的解法。

有收获?希望老铁们来个三连击,给更多的人看到这篇文章

1, thumbs up , so that more people can see the article
2, concerned about the original micro-channel public number " hard to force the code farmers ", in order to consolidate the basic knowledge of computer (computer network operating system + database + + Linux), and algorithms, recently opened a micro-channel public number " hard to force the code farmers " interested can focus, focus on explaining the algorithm related articles, hee hee. Background reply " e-book " to send you a selection of e-books spree, containing all kinds of skills of high-quality e-book

Guess you like

Origin www.cnblogs.com/kubidemanong/p/11949244.html