前端面试经典算法题

1.二叉树

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字,如果不存在则输出0

let arr = [1,2,2,2,3,2,4,2,5,2];

function binary_tree(numArr){
	let out = 0;
	let obj = {};
	let length = numArr.length/2;
	numArr.forEach(item =>{
		!obj[item]? obj[item] = 1:obj[item]++
	});
	for(let [key,value] of Object.entries(obj)){
	 if(value > length){
		out = key
	 }
	}
	return out;
}

binary_tree(arr);
2.斐波那契数列
function Fibonacci(n)
{
   if(n==0||n==1) {
       return n;
   }
    let a=0,b=1,c;
    for(let i=2;i<=n;i++){
        c = a+b;
        a = b;
        b = c;
    }
    return c;
}
Fibonacci(10);
3.两数之和

题目: 给定一个数组 nums 和一个目标值 target,在该数组中找出和为目标值的两个数

输入: nums: [8, 2, 6, 5, 4, 1, 3] ; target:7

输出: [2, 5]

// 时间复杂度O(n)、 空间复杂度O(n)
function twoNumAdd(arr, target) {
  if (Array.isArray(arr)) {
    // 使用map将遍历过的数字存起来,空间换时间
    let map = {};
    for (let i = 0; i < arr.length; i++) {
      // 从map中查找是否有key 等于 target-nums[i],如果有,则条件成立,返回结果
      if (map[target - arr[i]] !== undefined) {
        return [target - arr[i], arr[i]];
      } else {
        // 条件不成立,将该值存起来
        map[arr[i]] = i;
      }
    }
  }
  return [];
}
let arr = [8, 2, 6, 5, 4, 1, 3];
let target = 7
twoNumAdd(arr, target)
4.三数之和

题目: 给定一个数组nums,判断 nums 中是否存在三个元素a,b,c,使得 a + b + c = target,找出所有满足条件且不重复的三元组合

输入: nums: [5, 2, 1, 1, 3, 4, 6] ;target:8

输出: [[1, 1, 6], [1, 2, 5], [1, 3, 4]]

// 用`双端指针`的方式,将三数之和转化为两数之和
function findThree(arr, target) {
  // 先将数组从小到大排序
  arr.sort((a, b) => a - b)
  let result = [];
  for (let i = 0; i < arr.length; i++) {
    // 跳过重复的arr[i]值, 比如[2, 1, 1],跳过第二个1
    if (i && arr[i] === arr[i - 1]) continue;
    let left = i + 1;
    let right = arr.length - 1;
    
    // 双端指针left、right
    while (left < right) {
      let sum = arr[i] + arr[left] + arr[right];
      if (sum > target) {
        right--;
      } else if (sum < target) {
        left++;
      } else {
        // 先取arr[left],然后left++, 两步合成一步;arr[right--]同样的逻辑
        result.push([arr[i], arr[left++], arr[right--]]);
        while (arr[left] === arr[left - 1]) {
          // 跳过重复的arr[left]值,
          left++;
        }
        while (arr[right] === arr[right + 1]) {
          // 跳过重复的arr[right]值
          right--;
        }
      }
    }
  }
  return result;
}

let arr = [5, 2, 1, 1, 3, 4, 6];
let target = 8;
findThree(arr,target)
5.版本号排序

题目: 输入一组版本号,输出从大到小的排序

输入: ['2.1.0.1', '0.401.1', '10.2.1', '5.1.2', '1.0.4.5']

输出: ['10.2.1', '5.1.2', '2.1.0.1', '1.0.4.5', '0.401.1']

function versionSort(arr) {
  return arr.sort((a, b) => {
    let i = 0;
    const arr1 = a.split(".");
    const arr2 = b.split(".");
    while (true) {
      // 取出相同位置的数字
      const s1 = arr1[i];
      const s2 = arr2[i];
      i++;
      // 若s1 或 s2 不存在,说明相同的位置已比较完成,接下来比较arr1 与 arr2的长度,长的版本号大
      if (s1 === undefined || s2 === undefined) {
        return arr2.length - arr1.length;
      }
      if (s1 === s2) continue;
      // 比较相同位置的数字大小
      return s2 - s1;
    }
  });
}

let arr =  ['2.1.0.1', '0.401.1', '10.2.1', '5.1.2', '1.0.4.5']
versionSort(arr)

6.数组扁平化

(1).使用递归的方式

function flattenArray(arr) {
  let flatArr = [];

  arr.forEach(item => {
    if (Array.isArray(item)) {
      // 递归处理子数组
      flatArr = flatArr.concat(flattenArray(item));
    } else {
      // 添加非数组元素到结果数组
      flatArr.push(item);
    }
  });

  return flatArr;
}

// 示例用法
const nestedArray = [1, [2, [3, 4], 5], 6];
const result = flattenArray(nestedArray);
console.log(result);

(2).实现数组扁平化的方式是使用flatMap()方法和展开运算符(spread operator)。flatMap()方法用于将数组中的每个元素映射到一个新数组,并将所有结果合并为一个新数组。然后,使用展开运算符将嵌套的子数组展开。

function flattenArray(arr) {
  return arr.flatMap(item => Array.isArray(item) ? flattenArray(item) : item);
}

// 示例用法
const nestedArray = [1, [2, [3, 4], 5], 6];
const result = flattenArray(nestedArray);
console.log(result); // 输出 [1, 2, 3, 4, 5, 6]

(3).利用循环

function flatten(arr) {
    while(arr.some(item => Array.isArray(item))){

        arr = [].concat(...arr);
    }
    return arr;

}
flatten([1, [2, [3, 4], 5], 6]);


 

猜你喜欢

转载自blog.csdn.net/weixin_38822843/article/details/131381492