算法题
1、合并两个有序数组,时间复杂度为O(n)
思路:两个指针,从零开始,比较两个数组里面的指针,每次把两者之中最小的放到结果数组中来。
const getOrderList = (list1, list2) => { let newList = []; let i = 0; let j = 0; while (i < list1.length && j < list2.length) { if (list1[i] <= list2[j]) { newList.push(list1[i]); i++; } else { newList.push(list2[j]); j++; } } if (i === list1.length) { newList = newList.concat(list2.slice(j)); } if (j === list2.length) { newList = newList.concat(list1.slice(i)); } return newList; };
2、判断一个单词是否回文
思路:
1、把字符串翻转之后,看是否等于原来的字符
const isRecerseValue = (value = '') => { let newValue = '' let i = value.length-1 while(i>=0) { newValue +=value[i] i--; } return newValue === value } console.log(isRecerseValue('aba'))
2、用首尾两个指针,向中间扫描字符串,如果两指针指向的字符都一样, 这字符串就是一个回文。
const isRecerseValue = (value = '') => { let i = 0; let j = value.length - 1; while (i < j) { if (value[i] !== value[j]) { return false; } i++; j--; } return true; };
3、求一个数组中的两数之和为target,输出两个数的index
1、暴力计算,
const target2element = (list = [], target) => { for (let i = 0; i < list.length-1; i++){ for (let j = i + 1; j < list.length; j++){ if(list[i]+list[j] === target){ return [i,j] } } } return [] }
2、使用hash表,把数组 的index,value生成 hash,对于一个list[i],判断target-list[i]是否在map中
const target2element = (list = [], target) => { const hashMap = new Map(); for (let i = 0; i < list.length; i++) { if (hashMap.has(target - list[i])) { return [i, hashMap.get(target - list[i])]; } hashMap.set(list[i], i); } };
4、给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a ,b ,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
思路:排序一下(解决不重复的问题),然后固定一个数之后,用双指针夹逼的原则。
补充:如果不规定重复,那么可以用3中的相似的手法
const sum2tree = (list = [], target) => { const result = []; if (list.length < 3) { return result; } list.sort((a, b) => a - b); for (let i = 0; i < list.length - 2; i++) { if (list[i] > 0) { break; } let left = i++; let right = list.length - 1; // 双指针夹逼 while (left < right) { const sum = list[i] + list[left++] + list[right++]; if (sum === 0) { // push 了之后防止还有重复的。 while (list[left] === list[left - 1]) { left++; } while (list[right] === list[right + 1]) { right++; } } else if (sum > 0) { right--; } else { left++; } } } };
5、求一个数组中的所有字符串的公共前缀。
思路:拿出数组中的第一个字符串,然后该字符串中的currentElement,用reduce的方法与list中的所有字符串中的currentIndex位置处的
const maxPrefix = (list = []) => { let currentIndex = 0; let isContinue = true; if(isContinue){ let currentValue = list[0][currentIndex]; const isCurrentComm = list.reduce((total,str) => str[currentIndex] === currentValue); if(isCurrentComm){ currentIndex++ } else{ isContinue = false; } return list[0].slice(0, currentIndex) } }
6、找出字符串中的最长无重复子串。
思路:
遍历字符串,并将字符串的value和index形成map结构,判断当前操作的字符串是否存在map中,如果不存在说明没有重复,继续遍历;
左右两个之间是无重复的子串,有重复,则需更新左指针i,从i之后找新的最大子串。
const maxSubString = (str) => { let max = 0,maxValue = ''; let map = new Map(); for (let i = 0, j=0; j < str.length; j++) { // 当memoy中包括有现在正在遍历的值时,且改元素在i和j之间的时候,更新i的值 if (map.has(str[j]) && map.get(s[j]) >= i) { i = map.get(str[j])+1; } if(j-i+1 > max) { max = j-i+1; maxValue = str.slice(i,j+1); } map.set(str[j], j); } } console.log(maxSubString('abcababbb'))
7、消消乐,消除相邻的相同字母。
思路:利用栈的原理
const xioaxioale = (str) => { let temp = []; for (let i = 0; i < str.length; i++) { let pre = temp.pop(); if(pre != str[i]){ temp.push(pre); temp.push(str[i]); } } return temp.join(''); } console.log(xioaxioale('abbababbb')) // bab