时间复杂度看运行情况,空间复杂度看占用的空间
冒泡排序:
export default (arr) => {
// 冒泡排序
for (let i = arr.length - 1, tmp; i > 0; i--) {
for (let j = 0; j < i; j++) {
tmp = arr[j]
if (tmp > arr[j + 1]) {
arr[j] = arr[j + 1]
arr[j + 1] = tmp
}
}
}
return arr
}
选择排序:
//选择排序
export default (arr) => {
// 选择排序
for (let i = 0, len = arr.length, min; i < len; i++) {
min = arr[i]
for (let j = i + 1; j < len; j++) {
if (arr[j] < min) {
let c = min
min = arr[j]
arr[j] = c
}
}
arr[i] = min
}
return arr
}
常规做法:
export default (arr) => {
// 如果数组长度小于2返回0
if (arr.length < 2) {
return 0
}
// 排序
arr.sort()
// 用它来保存相邻元素的最大差值
let max = 0
for (let i = 0, len = arr.length - 1, tmp; i < len; i++) {
tmp = arr[i + 1] - arr[i]
if (tmp > max) {
max = tmp
}
}
return max
}
export default (arr) => {
if (arr.length < 2) {
return 0
}
let max = 0
let len = arr.length - 1
let space
for (let i = len, tmp; i > 0; i--) {
for (let j = 0; j < i; j++) {
tmp = arr[j]
if (tmp > arr[j + 1]) {
arr[j] = arr[j + 1]
arr[j + 1] = tmp
}
}
if (i < len) {
space = arr[i + 1] - arr[i]
if (space > max) {
max = space
}
}
}
return Math.max(max, arr[1] - arr[0])
}
export default (arr) => {
// 进行升序排序
arr.sort((a, b) => a - b)
// 声明一个空数组用来存储奇偶排序后的数组
let r = []
// 记录奇数、偶数位下标
let odd = 1
let even = 0
// 对数组进行遍历
arr.forEach(item => {
if (item % 2 === 1) {
r[odd] = item
odd += 2
} else {
r[even] = item
even += 2
}
})
return r
}
export default (arr,k)=>{
arr.sort((a,b)=>b-a)[k-1]
}
export default (arr, k) => {
let len = arr.length - 1
for (let i = len, tmp; i > len - k; i--) {
for (let j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
tmp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = tmp
}
}
}
// arr[len+1-k]
return arr[len - (k - 1)]
}
export default (arr) => {
// 过滤掉非正整数
arr = arr.filter(item => item > 0)
// 正整数数组是不是为空
if (arr.length) {
// 升序,目的:方便从左到右取最小值arr[0]
arr.sort((a, b) => a - b)
// 如果第一个元素不为1,返回1
if (arr[0] !== 1) {
return 1
} else {
// 从左边开始遍历,只要下一个元素和当前元素差值》1说明当前元素的下一个值(+1)
for (let i = 0, len = arr.length - 1; i < len; i++) {
if (arr[i + 1] - arr[i] > 1) {
return arr[i] + 1
}
}
// 如果数组是连续的正整数【1,2,3,4,5,6】
return arr.pop() + 1
}
} else {
return 1
}
}
export default (arr) => {
arr = arr.filter(item => item > 0)
// 实现选择排序,先拿到最小值,如果第一个元素不是1直接返回1,如果是1,就要比相邻元素差值
for (let i = 0, len = arr.length, min; i < len; i++) {
min = arr[i]
for (let j = i + 1; j < len; j++) {
if (arr[j] < min) {
let c = min
min = arr[j]
arr[j] = c
}
}
arr[i] = min
if (i > 0) {
if (arr[i] - arr[i - 1] > 1) {
return arr[i - 1] + 1
}
} else {
if (min !== 1) {
return 1
}
}
}
return arr.length ? arr.pop() + 1 : 1
}
递归:
export default (str) => {
// 保存所有符合条件的IP地址
let r = []
// 分四步递归处理ip分段
let search = (cur, sub) => {
// 边界条件
if (cur.length === 4 && cur.join('') === str) {
r.push(cur.join('.'))
} else {
// 正常的处理过程
for (let i = 0, len = Math.min(3, sub.length), tmp; i < len; i++) {
tmp = sub.substr(0, i + 1)
if (tmp < 256) {
search(cur.concat([tmp]), sub.substr(i + 1))
}
}
}
}
search([], str)
return r
}
拆分单词:
export default (str, words) => {
// 保存结果
let result = []
// 记录数组的长度,做边界条件计算
let num = words.length
// 递归函数体
let range = (r, _arr) => {
if (r.length === num) {
result.push(r)
} else {
_arr.forEach((item, idx) => {
let tmp = [].concat(_arr)
tmp.splice(idx, 1)
range(r.concat(item), tmp)
})
}
}
range([], words)
// [0, 9, -1] filter 之后[0,9]
return result.map(item => {
return str.indexOf(item.join(''))
}).filter(item => item !== -1).sort()
}
棒球求和
export default (arr)=>{
//用数组实现堆栈结构 pop push
let result=[]
//上一轮的数据
let pre1
//上上轮的数据
let pre2
//对数组进行遍历,遍历的目的是处理得分
arr.forEach(item=>{
switch(item){
case 'C':
if(result.length){
result.pop()
}
break
case 'D':
pre1=result.pop()
result.push(pre1,pre1*2)
break
case '+':
pre1=result.pop()
pre2=result.pop(pre2,pre1,pre2+pre1)
break
default:
result.push(item*1)
}
})
return result.reduce((total,num)=>{return total+num})
}
export default (arr)=>{
let result=[]
let reg=/1{2,}/g
//把二维数组重新表达,把相邻的1提取出来(起始点+截止点)
arr= arr.map(item=>{
let str=item.join('')
let r=reg.exec(str)
let rs=[]
while(r){
rs.push([r.index,r.index + r[0].length-1]) //起始位置和结尾位置
r=reg.exec(str)
}
return rs
})
//通过递归计算相邻的矩阵
let maxRect=(arr,result,n=1)=>{
//弹出第一行
let top=arr.pop()
//弹出第二行
let next=arr.pop()
//记录第一行的每一个起始点和截止点
let tt
//记录第二行的每一个起始点和截止点
let nn
//记录交叉的起始索引
let start
//记录交叉的截止位置
let end
let width=1
let maxWidth=1
n++
for(let i=0,il=top.length;i<il;i++){
tt=top[i]
for(let j=0,jl=next.length;j<jl;j++){
nn=next[j]
width=Math.min(tt[1],nn[1])-Math.max(tt[0],nn[0])
if(width>maxWidth){
maxWidth=width
start=Math.max(tt[0],nn[0])
end =Math.min(tt[1],nn[1])
}
}
}
//如果没有找到交叉点
if(start===undefined||end===undefined){
if(n<3){
return false
}else{
width=rop[0][1]-top[0][0]+1
if(width>1){
result.push((n-1)*width)
}
}
}else{
arr.push([[start,end]])
maxRect(arr,result,n++)
}
}
while(arr.length>1){
maxRect([].concat(arr),result)
arr.pop()
}
//取最大值
let max=0
let item=result.pop()
while(item){
if(item> max){
max>=item
}
item=result.pop()
}
return max>0?max:-1
}