前端基础知识与常见面试题(十四)
如果字符串满足以下条件之一,则可以称之为 有效括号字符串(valid parentheses string,可以简写为 VPS):
字符串是一个空字符串 "",或者是一个不为 "(" 或 ")" 的单字符。
字符串可以写为 AB(A 与 B 字符串连接),其中 A 和 B 都是 有效括号字符串 。
字符串可以写为 (A),其中 A 是一个 有效括号字符串 。
类似地,可以定义任何有效括号字符串 S 的 嵌套深度 depth(S):
depth("") = 0
depth(C) = 0,其中 C 是单个字符的字符串,且该字符不是 "(" 或者 ")"
depth(A + B) = max(depth(A), depth(B)),其中 A 和 B 都是 有效括号字符串
depth("(" + A + ")") = 1 + depth(A),其中 A 是一个 有效括号字符串
例如:""、"()()"、"()(()())" 都是 有效括号字符串(嵌套深度分别为 0、1、2),而 ")(" 、"(()" 都不是 有效括号字符串 。
给你一个 有效括号字符串 s,返回该字符串的 s 嵌套深度 。
示例 1:
输入:s = "(1+(2*3)+((8)/4))+1"
输出:3
解释:数字 8 在嵌套的 3 层括号中。
示例 2:
输入:s = "(1)+((2))+(((3)))"
输出:3
提示:
1 <= s.length <= 100
s 由数字 0-9 和字符 '+'、'-'、'*'、'/'、'('、')' 组成
题目数据保证括号表达式 s 是 有效的括号表达式
解:/**
*
* @param s string字符串
* @return bool布尔型
*/
function isValid(s) {
// write code here
let arr = []
for (var i = 0; i < s.length; i++) {
if (s[i] == "(" || s[i] == "{" || s[i] == "[") {
arr.push(s[i])
}else
if (s[i] == ")" && arr.slice(-1) == "(" ||
s[i] == "}" && arr.slice(-1) == "{" ||
s[i] == "]" && arr.slice(-1) == "["){
arr.pop()
}else{
arr.push(s[i])
}
}
if(arr.length==0 ){
console.log(arr)
return true
}else{
console.log(arr)
return false
}
}
module.exports = {
isValid: isValid,
};
——————————————————————
有重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合。
示例1:
输入:S = "qqe"
输出:["eqq","qeq","qqe"]
示例2:
输入:S = "ab"
输出:["ab", "ba"]
提示:
字符都是英文字母。
字符串长度在[1, 9]之间。
解:
/**
* @param {string} S
* @return {string[]}
*/
var permutation = function(S) {
let arr=[]
let tar=S.split("")
let m=[...tar]
function pai(ok,old){
if(ok.length==tar.length){
arr.push(ok.join(''))
}else{
for(var i=0;i<old.length;i++){
let f=[...old]
f.splice(i,1)
pai(ok.concat(old[i]),f)
}
}
}
pai([],m)
return [...new Set(arr)].sort()
};
————————————————
concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。
push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。
区别:
1,push()是在原数组的基础上修改的,执行push()方法后原数组的值也会变;concat()是先把原数组复制到一个新的数组,然后在新数组上进行操作,所以不会改变原数组的值。
2,如果参数不是数组,push()和concat()都会直接把参数添加到数组后;如果参数是一个数组,push()就会直接把数组添加到原数组后,而concat()会把数组里的值取出来添加到原数组的后面。
——————————————————
给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。
连续递增的子序列 可以由两个下标 l 和 r(l < r)确定,如果对于每个 l <= i < r,都有 nums[i] < nums[i + 1] ,那么子序列 [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]] 就是连续递增子序列。
示例 1:
输入:nums = [1,3,5,4,7]
输出:3
解释:最长连续递增序列是 [1,3,5], 长度为3。
尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为 5 和 7 在原数组里被 4 隔开。
示例 2:
输入:nums = [2,2,2,2,2]
输出:1
解释:最长连续递增序列是 [2], 长度为1。
解:(我的方法)
/**
* @param {number[]} nums
* @return {number}
*/
var findLengthOfLCIS = function(nums) {
let max=1
for(var i=0;i<nums.length;i++){
let n=1
for(var j=i+1;j<nums.length;j++){
if(nums[j-1]<nums[j]){
n++
max=Math.max(max,n)
}else{
break
}
}
}
return max
};
法二:(更简单的方法)
var findLengthOfLCIS = function(nums) {
if (nums.length < 1) { return 0 }
let max = 1
let len = 1
for (let i = 1; i < nums.length; i ++) {
if (nums[i] > nums[i - 1]) {
len++
max = Math.max(max, len)
} else {
len = 1
}
}
return max
};
————————————————————————
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回:
[3,9,20,15,7]
解:/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var levelOrder = function(root) {
if(root==null){return []}
let res=[root]
let kk=[]
while(res.length>0){
console.log(res)
let str=res.shift()
kk.push(str.val)
if(str.left){
res.push(str.left)
}
if(str.right){
res.push(str.right)
}
}
return kk
};
————————————————————————
从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
解:
var levelOrder = function(root) {
if (!root) return [];
var result = [], // 结果集
tmp = [root]; // 临时存储此层结点 以便后续依次取出
while (tmp.length) {
var childtmp = []; // 临时存储此层的所有子节点,一边下一次循环用做tmp来使用
var level = []; // 把每一层的val放入一个数组中,以便每一层结束后拼接进入结果集result
// console.log(tmp)
for (var i = 0, len = tmp.length; i < len; i++) {
level.push(tmp[i].val); // 每一層的去收集
// 有左右孩子时再去把左右孩子放进childtmp中
if (tmp[i].left)
childtmp.push(tmp[i].left);
if (tmp[i].right)
childtmp.push(tmp[i].right);
}
tmp = childtmp;
result.push(level);
}
return result;
};
————————————————————————
请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层次遍历结果:
[
[3],
[20,9],
[15,7]
]
解:/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function(root) {
if(!root){return []}
let res=[root]
let kk=[]
let nn=0
while(res.length>0){
nn=nn+1
let child=[]
let mm=[]
for(var i=0;i<res.length;i++){
mm.push(res[i].val)
if(res[i].left){
child.push(res[i].left)
}
if(res[i].right){
child.push(res[i].right)
}
}
if(nn%2==0){
let gg=mm.reverse()
kk.push(gg)
}else{
kk.push(mm)
}
res=child
}
return kk
};
————————————————————————
在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一:
值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。
返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1 。
示例 1:
输入:grid = [[2,1,1],[1,1,0],[0,1,1]]
输出:4
示例 2:
输入:grid = [[2,1,1],[0,1,1],[1,0,1]]
输出:-1
解释:左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个正向上。
示例 3:
输入:grid = [[0,2]]
输出:0
解释:因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0 。
——————————————————————————
/**
* @param {number[][]} grid
* @return {number}
*/
var orangesRotting = function(grid) {
let bad=[]
let fresh=0
let times=0
for(var i=0;i<grid.length;i++){
for(var j=0;j<grid[i].length;j++){
if(grid[i][j]==2){
bad.push([i,j])
}
if(grid[i][j]==1){
fresh++
}
}
}
console.log(bad.length)
console.log(fresh)
while(bad.length>0 && fresh>0){
let next=[]
let e=[0,0,1,-1]
let f=[1,-1,0,0]
while(bad.length>0 ){
let kk=bad.shift()
for(var i=0;i<e.length;i++){
let x=kk[0]+e[i]
let y=kk[1]+f[i]
if(x>=0 && y>=0 && x<grid.length && y<grid[x].length){
if(grid[x][y]==1){
fresh--
grid[x][y]=2
next.push([x,y])
}
}
}
}
// console.log(next)
bad=next
times++
}
return fresh==0 ? times : -1
};
————————————————————————————
给定整数 n ,返回 所有小于非负整数 n 的质数的数量 。
示例 1:
输入:n = 10
输出:4
解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
示例 2:
输入:n = 0
输出:0
示例 3:
输入:n = 1
输出:0
解:
var countPrimes = function(n) {
// 判断是否为质数
const isPrime = (n) => {
for(let i = 2; i*i <= n; i++) {
if(n % i === 0) {
return false;
}
}
return true;
}
let count = 0;
for(let i = 2; i < n; i++) {
if(isPrime(i)) {
count++;
}
}
return count;
};
————————————————————————
什么是高质量代码?
好的代码一定是整洁的,并且能够帮助阅读的人快速理解和定位。好的代码可以加快应用的开发迭代速度,
不必花过多的时间来修复 bug 和完善代码。好的代码不但能够使得新的项目成员更容易加入项目,同时方
便项目组成员快速做好 Back up。好的代码便于促进团队间交流合作提升开发效率。
一、代码质量评价标准
有编码经验的人对代码都有一定的“鉴赏力”,能够凭感觉给出代码好坏的主观评价。但是这种凭感觉的
方式太过个性随意,所谓仁者见仁智者见智,很难达成共识,那有没有一种公认的标准来鉴定代码质量呢?
答案是有的。这里简单分享当下较常用的评价标准,其中包括:编码规范、可读性、可维护性、重复度及可测试性。
1、编码规范
主要包含是否遵守了最佳实践和团队编码规范,是否包含可能出问题的代码,以及可能存在安全的漏洞。
编码规范有助于提高团队内协助的效率以及代码的可维护性。
2、可读性
Code Review 是一个很好的测验代码可读性的手段。如果你的同事可以轻松地读懂你写的代码,那说明你的
代码可读性很好;反之则说明你的代码可读性有待提高了。遵守编码规范也能让我们写出可读性更好的代码。
3、可维护性
代码的可维护性是由很多因素协同作用的结果。代码的可读性好、简洁、可扩展性好,就会使得代码易维护;
更细化地讲,如果代码分层清晰、模块化好、高内聚低耦合、遵从基于接口而非实现编程的设计原则等等,
那就可能意味着代码易维护。除此之外,代码的易维护性还跟项目代码量的多少、业务的复杂程度、利用到的
技术的复杂程度、文档是否全面等诸多因素有关。
4、重复度
遵守 Don’t Repeat Yourself 原则,尽量减少重复代码的编写,复用已有的代码。对项目定期进行代码重复度
检测是一个很有意义的事,可以帮助开发人员发现冗余代码,进行代码抽象和重构。重复的代码一旦出错,
意味着加倍的工作量和持续的不可控。如果代码中有大量的重复代码,就要考虑将重复的代码提取出来,
封装成公共的方法或者组件。
5、可测试性
代码可测试性的好坏,同样可以反应代码质量的好坏。代码的可测试性差,比较难写单元测试,那基本上就能说明代码设计得有问题。
————————————————————————————————————
如何看待加班?
要是工作需要,加班是可以接受的。因为我刚毕业(或孩子大,或单身等),时间和精力是也比较充裕的,
完全可以全身心的投入工作。同时,我也会提高工作效率,尽可能减少不必要的加班。
前端基础知识与常见面试题(十四)相关推荐
- Android开发必须掌握的Java基础知识和常见面试题
Java基础知识 面向对象特征 基本数据类型及装箱拆箱机制 String StringBuffer StringBuild final finally finalize 区别 static关键字 重写 ...
- html5 将id的值用于top_web前端分享HTML5常见面试题集锦四
web前端分享HTML5常见面试题集锦四 1.为什么要初始化CSS样式? 答案:因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对CSS初始化往往会出现浏览器之间的页面显示差异. 当 ...
- web前端HTML和CSS3常见面试题
web前端HTML和CSS3常见面试题 1.你常用的浏览器有哪些? 1: Chrome 内核 Webkit -> Blink 2: FireFox 火狐 内核 Gecko 开源 3: IE Tr ...
- BTA 常问的 Java基础40道常见面试题及详细答案,java初级面试笔试题
我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...
- BTA 常问的 Java基础40道常见面试题及详细答案
最近看到网上流传着,各种面试经验及面试题,往往都是一大堆技术题目贴上去,而没有答案. 为此我业余时间整理了,Java基础常见的40道常见面试题,及详细答案,望各路大牛,发现不对的地方,不吝赐教,留言即 ...
- 【JAVA秒会技术之秒杀面试官】JavaSE常见面试题(四)
[前言]别人都在你看不到的地方暗自努力,在你看得到的地方,他们也和你一样显得游手好闲,和你一样会抱怨,而只有你自己相信这些都是真的,最后,也只有你一个人继续不思进取 -- [下载]本人刚学习Jav ...
- “约见”面试官系列之常见面试题第四十篇之双向绑定以及实现原理(建议收藏)
目录 MVC模式 MVVM模式 双向绑定原理 1.实现一个Observer 2.实现一个Watcher 3.实现一个Compile 4.实现一个MVVM 最后写一个html测试一下我们的功能 MVC模 ...
- “约见”面试官系列之常见面试题第四十四篇之webpack打包原理解析?(建议收藏)
webpack打包是如何运行的 也可以称为,webpack是如何实现模块化的 CommonJS是同步加载模块,一般用于node.因为node应用程序运行在服务器上,程序通过文件系统可以直接读取到各个模 ...
- “约见”面试官系列之常见面试题第四十二篇之原型和原型链(建议收藏)
原型和原型链的理解:(面试题) 原型:每个函数都有 prototype 属性,该属性指向原型对象:使用原型对象的好处是所有对象实例共享它所包含的属性和方法. 原型链:主要解决了继承的问题:每个对象都拥 ...
最新文章
- 操作系统学习笔记 第二章:进程管理(王道考研)
- 关于大型网站技术演进的思考(四)-存储的瓶颈4
- WINCE6.0远程桌面显示修改
- 部分手机配置信息及价格
- 浅谈如何提升数据中心制冷能效
- 并发工具类(四)两个线程进行数据交换的Exchanger
- 这个网盘下载60MB/s!PanDownload复活了!
- 51单片机之特殊功能寄存器SFR
- Linux系统编程3:基础篇之详解Linux软件包管理器yum
- 硬件基础知识(13)---模拟电路中大量使用的滤波和隔直LC网络的值计算
- CDC::GetDeviceCaps()物理长度与屏幕像素间的转换
- 集成学习——NGBoost论文研读与原理理解
- linux每日命令(11):cat命令
- 《网络攻防》第十周学习总结
- 推荐几个e书下载地址
- springboot 操作es 之elasticsearch-rest-high-level-client
- Unity 游戏框架搭建 2017 (二十四) 小结
- 基于RecyclerView的图片浏览器
- 小丑改造计划之复习一
- 网络摄像头IPC国标GB28181协议国标安防视频流媒体平台EasyGBS视频流不上线排查步骤
热门文章
- 【猿创征文|Unity开发实战】—— 2D项目1 - Ruby‘s Adventure 游戏地图绘制(2-1)
- Carla中的joystick(wheel)方向盘控制
- 微信小程序获取的语言列表统计,微信小程序getSystemInfo获取的各种语言都叫什么?微信小程序国际化|多语言版本获取微信小程序语言大全【记录】
- java毫秒级别定时器
- Ubuntu把数据从一个硬盘完全拷贝到另一个硬盘的方法
- 魔鬼WIFI名字密码“数字学家可以猜到”
- 云原生模式--设计拥抱变化的软件(三)
- linux怎么压缩目录dir1,怎么在linux压缩一个文件夹?
- VNote Markdown 工具 <ubuntu>
- Pandas+Pyecharts | 40000+汽车之家数据分析可视化