【图解】记一次手撕算法面试:字节跳动的面试官把我四连击了
以下文章来源于苦逼的码农 ,作者帅地
字节跳动这家公司,应该是所有招聘公司中,对算法最重视的一个了,每次面试基本都会让你手撕算法,今天这篇文章就记录下当时被问到的几个算法题,并且每个算法题我都详细着给出了最优解,下面再现当时的面试场景,看完一定让你有所收获。
一、小牛试刀:有效括号
大部分情况下,面试官都会问一个不怎么难的问题,不过你千万别太开心,因为这道题往往可以拓展出更多有难度的问题,或者一道题看起来很简单,但是给出最优解,确实很不容易的。这道题是这样的:
给定一个只包括 '(',')'的字符串,判断字符串是否有效。注:空字符串属于有效字符串。
示例 1:输入: "(())"输出: true实例 2:输入: "())("输出: false
其实这道题的 leetcode 第 20 题的简化版,属于 easy 级别
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;elsestack.pop();}}// 判断是否为空if(stack.isEmpty())return true;return false;}
二、优化
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;elsesum--;}}return sum == 0 ? true : false;}
三、最长有效括号
给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:输入: "(()"输出: 2解释: 最长有效括号子串为 "()"示例 2:输入: ")()())"输出: 4解释: 最长有效括号子串为 "()()"
其实这道题就是 leetcode 的原题,第 32 题,难度为 hard。
把第二个字符作为首字符,则 max = 0 (一开始就是 ')',显然啥也匹配不了)
把第三个字符作为首字符,则 max = 0
把第四个字符作为首字符,则 max = 4
…..
这种做法的时间复杂度为 O(n^2),空间复杂度为 O(1)。
基本上面那道题一样,只是做了 n 次遍历。
2、、对于遇到的每个 '(' ,我们将它的下标放入栈中。
3、对于遇到的每个 ‘)’ ,我们弹出栈顶的元素并将当前元素的下标与弹出元素下标作差,得出当前有效括号字符串的长度。
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;}
四、最后一击
public int longestValidParentheses(String s) {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;}
总结
对话阿里云叔同:释放云价值,让容器成为“普适”技术 华为美国研发中心将迁至加拿大;高通CEO否认中国5G超美国:技术上还没有,顶多算并驾齐驱;亚马逊宣布进军量子界…… 苹果公司 50% 员工没大学学历,细数不看学历看能力的 IT 大佬! 我收集了12款自动生成器,无聊人士自娱自乐专用 腾讯安全全面出击:双十一不该成为黑产的狂欢
【建议珍藏系列】如果你这样回答「什么是线程安全」,面试官都会对你刮目相看!