每日JavaScript - 11 十种数组去重方法,寻找最长子串的长度

csd题目1
给定一个字符串,找出不含有重复字符的最长子串长度
如 ‘abcabcbb’ 输出3,子串为abc
‘pwwkew’ 输出3,子串为wke
‘bbbbbb’ 输出1, 字串为b

感觉自己以前做过这题,也是非常基础的题目

let test1 = 'abcabcbb'
let test2 = 'pwwkew'
let test3 = 'bbbbbbb'
function findLen(str) {
	let res = 0
	let temp = []
	let len = str.length
	for (let i = 0; i < len; i++) {
		if (!temp.includes(str[i])) {
			temp.push(str[i])
		} else {
			if (temp.length > res) {
				res = temp.length
			}
            temp.length = 0
            temp.push(str[i])
		}
	}
	return res
}

console.log(findLen(test1))
console.log(findLen(test2))
console.log(findLen(test3))

掘金大佬版本

function findLen(s) {
	let map = new Map()
	let start = -1,
	    maxLen = 0
	arr = s.split("")

	arr.forEach((element, index, arr) => {
		if (map.has(element)) {
			start = Math.max(map.get(element), start)
		}
		map.set(element, index)
		maxLen = Math.max(index-start, maxLen)
	})
	return maxLen
}

我觉得我的写法比较简单易懂吧,大佬用了Map,这个不太懂。
题目2
再贴一个黄老师在沸点提出的问题吧。

console.log(1 == [1]);   // true
console.log('1' == [1]);  // true

== 会默认进行隐式转换,[1]先调用valueof返回自身,再调用toString返回’1’,所以两个console.log都输出true。
题目3
创建一个6x6的二维数组,元素全为1

function twoD(num) {
	let i = num 
	let res = new Array(num)
	while (i) {
		res[i - 1] = new Array(num).fill(1)
		i --
	}
	return res
}

二维数组可以如此简单创建

var A=new Array(10);
for(var i=0;i<10;i++){
    A[i]=new Array(10);
}

题目4
给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。

function findMost(arr) {
	arr.sort()
	// return arr[Math.floor(arr.length / 2)]
	// 右移一位
	return arr[arr.length >> 1]
}
let test = [2,2,1,1,1,2,2]
console.log(findMost(test))

题目5
尽可能的写出多的数组去重方法
(这只能用来去除基本类型,对于像对象引用类型要这门写个比较函数来去重,因为对象可能多层嵌套,所以不好比较,未来我写写这个函数吧)

方法1:使用sort(),对比相邻两个元素,相同就去除。

function unique(arr) {
	let res = []
	let len = arr.length
	let i = len
	arr.sort()
	while (i) {
        if (arr[len - i] !== arr[len - i -1]) {
        	res.push(arr[len - i])
        }
		i --
	}
	return res
}
let test = [2,2,1,1,1,2,2]
console.log(unique(test))

方法2: 使用对象的键是唯一的特性,进行去重。

obj[arr[i]] = 0

注意这个方法有个小坑,不能赋给0,因为if (!obj[arr[i]]) 会隐式转换,使得判断永远为true

function unique(arr) {
	let res = []
	let obj = {}
	let len = arr.length
	let i = 0
	while (i < len) {
		if (!obj[arr[i]]) {
		//  不能标记为0
			obj[arr[i]] = 1 
			res.push(arr[i])
		}
		i ++ 
	}
	return res
}
console.log(unique(test))

方法3: 使用ES6中的set进行去重

// 就是这么短
let unique = (arr) => [...new Set(arr)]

方法4: 创建新的数组使用includes判断是否去重

function unique(arr) {
	let res = []
	let len = arr.length
	let i = 0
	while(i < len){
		if (!res.includes(arr[i])) {
			res.push(arr[i])
		}
		i ++
    }   
	return res
}
console.log(unique(test))

方法5: 利用filter 注意self代指数组本身

const distinct = arr => arr.filter( (element, index, self) => {
    return self.indexOf( element ) === index;
});

let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
distinct(arr); // [1, 2, 3, 5, 4]

方法6:利用indexOf和 lastIndexOf,在原数组更改。

function unique(arr) {
  for (let i = 0; i < arr.length >> 1; i++) {
    console.log(arr.length)
    if (arr.indexOf(arr[i]) !== arr.lastIndexOf(arr[i])) {
      arr.splice(arr.lastIndexOf(arr[i]), 1)
      // 遇到重复元素后,删除后面的元素后再检查前面是否有相同的元素
      i--
    }
  }
  return arr
}

let array = [11,22,33,44,55,22,33,54]
console.log(unique(array))

方法7: 使用双循环

function uniqueArr(arr) {
  for (let i = 0; i < arr.length; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[i] === arr[j]) {
        arr.splice(j, 1)
        j--
      }
    }
  }
  return arr
}

方法8 使用hasOwnProperty和typeof

function uniqueArray(arr) {
  let obj = {}
  return arr.filter((item, index, arr) => 
    obj.hasOwnProperty(`${typeof item} ${item}`) ? false : (obj[`${typeof item} ${item}`] = 1)
  )
}

let testArr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}]
console.log(uniqueArray(testArr))

方法9: 使用Map

function arrayNonRepeatfy(arr) {
  let map = new Map()
  let array = []
  for (let i = 0; i < arr.length; i++) {
    if (map.has(arr[i])) {  
      map.set(arr[i], true)
    } else { 
      map.set(arr[i], false)
      array.push(arr[i])
    }
  } 
  return array 
}

方法10: 使用reduce

const uni = arr => arr.reduce((acc, cur) => acc.includes(cur) ? acc : [...acc, cur], [])
let arr = [1, 2, 3, 1, 1, 2, 3, 3, 4, 3, 4, 5]

let result = arr.reduce((prev, item, index, arr) => {
!prev.includes(item) && prev.push(item);
return prev
}, [])
console.log(result);  //[1, 2, 3, 4, 5]

&& 操作符会检查第一个参数是否为true,当第一个操作数为false时,不会对第二个操作数进行求职。相反,如果第一个操作数为true时,则会对第二个操作数进行求值。

希望这是我最后一次写数组去重。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值