碎碎念:
亲爱的读者:你好!我的名字叫昌龙 【Changlon】 —— 一个非科班程序员、一个致力于前端的开发者、一个热爱生活且又时有忧郁的思考者。
如果我的文章能给你带来一些收获,你的点赞收藏将是对我莫大的鼓励!
我的邮箱:thinker_changlon@163.com
我的Github: https://github.com/Changlon
程序员之进大厂必刷算法题系列
数组
字符串
链表
栈
哈希
二叉树
二分算法
分治算法(快排序)
动态规划
深度优先,广度优先算法
递归,回溯算法
贪心算法
文章目录
一、NC22 合并两个有序的数组
描述 给出一个整数数组 A 和有序的整数数组B ,请将数组 B合并到数组 A中,变成一个有序的升序数组 注意:
1.可以假设 A数组有足够的空间存放 B数组的元素,A 和 B中初始的元素数目分别为 m和 n,A的数组空间大小为 m+n
2.不要返回合并的数组,返回是空的,将数组B 的数据合并到A里面就好了
3.A数组在[0,m-1]的范围也是有序的例1: A: [1,2,3,0,0,0],m=3 B: [2,5,6],n=3 合并过后A为: A: [1,2,2,3,5,6]
示例1
输入:
[4,5,6],[1,2,3]
复制
返回值:
[1,2,3,4,5,6]
思路1: 首先将B数组中的数据拷贝到A的剩余空间中,然后对A数组使用sort排序,最后返回A。
function merge( A, m, B, n ) {
for(let i =m,j=0;i<m+n;++i,++j) {
A[i] = B[j]
}
A.sort((a,b)=>a-b)
return A
}
那么如果面试官这时候提了一个不能使用原型或类库函数的要求呢?我们不能使用sort库函数或原型函数。
思路2:因为A数组和B数组都是升序的,所以我们可以用双指针来处理这道题。
初始化 m,n分别指向A和B的尾部。然后开始从尾部向前比较大小,谁的值大就放到A数组的后面。接着只移动那个较大的指针先前一个再继续比较。如果B中的数都比A中的大,那么遍历一遍正好都放满A的剩余空间。如果B中的最小值比A中的最小值小,那么遍历一遍过后n一定是大于0的,那就将B中前n个元素拷贝到A前n个位置中。
function merge(A,m,B,n) {
let len1 = A.length,len2 = B.length
if(len1==0) {
for(let n of B) A.push(n)
return A
}
if(len2==0) return A
while(m>0&&n>0) {
if(A[m-1]>=B[n-1]) {
A[m+n-1] = A[m-1]
m--
}else{
A[m+n-1] = B[n-1]
n--
}
}
//处理B中小于A最小数的数
if(n>0) {
for(let i =0;i<n;++i) A[i] = B[i]
}
return A
}
二、NC41 最长无重复子数组
描述 给定一个数组arr,返回arr的最长无重复元素子数组的长度,无重复指的是所有数字都不相同。
子数组是连续的,比如[1,3,5,7,9]的子数组有[1,3],[3,5,7]等等,但是[1,3,7]不是子数组
示例1 输入:
[2,3,4,5]
返回值: 4
说明: [2,3,4,5]是最长子数组
示例2 输入: [2,2,3,4,3]
返回值: 3
说明:[2,3,4]是最长子数组
思路1: 定义一个队列,遍历数组依次将数据添加至队列中,如果将要添加的内容与在队列中重复,则将重复的内容以及重复前面的内容循环出队列。之后再向队列中添加数据,接着比较是否是最长不重复子数组。
function maxLength(arr) {
if(arr.length==0||arr.length==1) return arr.length
const queue = []
let max = 0
for(let c of arr) {
while(queue.includes(c)) {
queue.shift()
}
queue.push(c)
max = Math.max(max,queue.length)
}
return max
}
思路2: 使用双指针,初始化i,j指针指向数组首地址,然后依次将i向后移动,顺便将每次移动的值添加至一个map中。如果当前i所在的位置中的值在map中重复,则将j向后移动。
function maxLength_( arr )