算法初级上

算法初级

有些根据LeetCode来的,一些是自己写的。
1.给定一个整数数组,判断是否存在重复元素。如果存在一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false 。

function unique(arr) {
  for (let i = 0; i < arr.length; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[i] == (arr[j])) {
        return false
      } else {
        return true
      }
    }

  }

}

2.给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

第一种方法

/**
*使用indexOf找到开始的第一个位置,在使用lastIndexOf找到最后一次出现的位置,剩下的就是只出现一次的
*/
function unique(arr) {
  let a=[]
  for (let i = 0; i < arr.length; i++) {
    if (arr.indexOf(arr[i]) == arr.lastIndexOf(arr[i])) {
      a.push(arr[i])
    }
  }
  return a
}

第二种方法

// 异或运算 相同值的二进制为1 不同值的二进制为0
//
function unique(arr) {
  for (let i = 1; i < arr.length; i++) {
    // arr[0]=arr[0]^arr[i] 等价下面
    arr[0] ^= arr[i]
  }
  return arr[0]
}
console.log(unique([4, 1, 2, 1, 2]));

3.给定两个数组,编写一个函数来计算它们的交集。

/**
*Set先去重,然后用Array.from将其转换成数组格式的;
*再依次循环,两两比较
*/
function unique(arr1, arr2) {
  let intersection = Array.from(new Set(arr1))
  let intersection2 = Array.from(new Set(arr2))
  let array=[]
  for (let i = 0; i < intersection.length; i++) {
    for (let j = 0; j < intersection2.length; j++) {
      if (intersection[i] == intersection2[j]) {
        array.push(intersection[i])
      }
    }
  }
  return array
}
console.log(unique(nums1 = [4, 9, 5], nums2 = [9, 4, 9, 8, 4]));
//交集的第二种方法,filter和indexOf结合
function unique(arr1, arr2) {
  let intersection = Array.from(new Set(arr1))
  let intersection2 = Array.from(new Set(arr2))
  let a = intersection.filter(item=> intersection2.indexOf(item) > -1)
  return a;
}

4.给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。说明:必须在原数组上操作,不能拷贝额外的数组。尽量减少操作次数。

//找到数组中为0的数,将其push到原数组后面;再删去原数组中0的位置
function unique(arr1) {
  for (let i = 0; i < arr1.length; i++) {
    if (arr1[i] == 0) {
      arr1.push(arr1[i])
      arr1.splice(i, 1)
    }
  }
  return arr1
}

5.给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。

/**
*两次循环,indexOf找出数组中数的出现的第一次的位置
*/
function unique(arr1, num) {
  let index = []
  for (let i = 0; i < arr1.length; i++) {
    for (let j = i + 1; j < arr1.length; j++) {
      if (arr1[i] + arr1[j] == num) {
        index.push(arr1.indexOf(arr1[i]), arr1.indexOf(arr1[j]))
        break
      }
    }
    return index
  }
}

6.根据年龄排序,年龄相同看身高,身高相同看体重.

var list = [{
    age: 3,
    height: 1,
    weight: 2,
}, {
    age: 1,
    height: 2,
    weight: 3,
}, {
    age: 1,
    height: 1,
    weight: 3,
}, {
    age: 1,
    height: 1,
    weight: 1,
}];

function sortArr(params, ...what) {
    let resultArr = []
    if (params.length===1||what.length === 0) {
      return params
    } else {
      let tempArr1 = [], tempWhat = what.slice(), tempArr = params.sort((a, b) => a[what[0]] - b[what[0]]), num = 0;
      while (tempArr.length>0) {
        let arr0 = [], index = 0, i = 0;
        arr0.push(tempArr[0])
        tempArr.splice(0, 1)
        while (i < tempArr.length) {
          if (arr0[0][what[0]] === tempArr[i][what[0]]) {
            arr0.push(tempArr[i])
            index += 1
          }; i++
        }
        tempArr1.push(arr0)

        tempArr = tempArr.slice(index)
      }
      tempWhat.splice(0, 1)
      while (num < tempArr1.length) {
        resultArr.push(...sortArr(tempArr1.slice()[num], ...tempWhat))
        num++
      }
    }
    return resultArr
  }
  console.log(sortArr(list, "age", "height", "weight"));

7.编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出,原地修改输入数组.

function unique(s) {
  let i=0;
  let j=s.length-1;
  while(i < j){
      const temp = s[j];
      s[j] = s[i];
      s[i] = temp;
      i++;
      j--;
  }
  return s
};

8.两个乱序数组,找出后一个比前一个数组大的组合.

第一种方法
function sortP(a, b) {
  return a - b
}
function s(a, b) {
  var aa = a.sort(sortP)
  var bb = b.sort(sortP)
  for (const i of aa) {
    for (const j of bb) {
      var cc = []
      var n = 0
      if (i < j) {
        cc.push(i)
        cc.push(j)
      }
    }
  }
}

console.log(s([1, 2], [1, 2, 3]), '11');

第二种方法
function s(a, b) {
  const cc = []
  for (let j = 0; j < b.length; j++) {
    if (b[j] > a[0]) {
      for (let i = j + 1; i < b.length; i++) {
        if (b[i] > a[1]) {
          cc.push([b[j], b[i]])
        }
      }
    }
  }
  return cc
}

第三种方法
function s(a, b) {
  const jj = []
  for (let x = 0; x < a.length; x++) {
    for (let y = x + 1; y < a.length; y++) {
      jj.push([a[x], a[y]])
    }
  }
  const cc = []
  for (let m = 0; m < jj.length; m++) {
    for (let j = 0; j < b.length; j++) {
      if (b[j] >= jj[m][0]) {
        for (let i = j + 1; i < b.length; i++) {
          if (b[i] >= jj[m][1]) {
            cc.push([b[j], b[i]])
          }
        }
      }
    }

  }
  return cc
}

9.找出字符串中短的字符串在长字符串中最短的截取内容.

let S = "agsdasf", T = "fgd"
function name(a, b, L) {
  var bool;
  if (L + b.length > a.length) return "没有"
  for (var i = 0; i <= a.length - b.length; i++) {
    bool = true
    var string = a.substring(i, i + b.length + L)
    for (var j = 0; j < b.length; j++) {
      if (!string.includes(b[j])) {
        bool = false;
        break
      }
    }
    if (bool) { return string }

  }
  return name(a, b, L + 1)
}
console.log(name(S, T, 0));

10.两个排序好的数组,将其合并为一个数组并排序。

//shift() 方法,删除数组第一个元素并改变原数组;
**第一种方法**
function name(nums1, nums2) {
  const arr = []
  while (nums1.length && nums2.length) {
    if (nums1[0] > nums2[0]) {
      arr.push(nums2.shift()
    } else {
      arr.push(nums1.shift())
    }
  }
  while (nums2.length) {
    arr.push(nums2.shift())
  }
  while (nums1.length) {
    arr.push(nums1.shift())
  }
  return arr
}

**第二种方法**

11.一个二维数组,依次将第一个数组的字符与后续数组的每个字符相组合;例如:输入[[1, 2, 3], [4, 5, 6], [7, 8, 9]],输出[ [ '1,4,7' ], [ '1,4,8' ], [ '1,4,9' ], [ '1,5,7' ], [ '1,5,8' ], [ '1,5,9' ], [ '1,6,7' ], [ '1,6,8' ], [ '1,6,9' ], [ '2,4,7' ], [ '2,4,8' ], [ '2,4,9' ], [ '2,5,7' ], [ '2,5,8' ], [ '2,5,9' ], [ '2,6,7' ], [ '2,6,8' ], [ '2,6,9' ], [ '3,4,7' ], [ '3,4,8' ], [ '3,4,9' ], [ '3,5,7' ], [ '3,5,8' ], [ '3,5,9' ], [ '3,6,7' ], [ '3,6,8' ], [ '3,6,9' ] ]

function a(array) {
   array.reduce((last, el) => {
    var arr = [];
    last.forEach(e1 => {
      el.forEach(e2 => {
        arr.push([e1 + "," + e2])
      })
    })
    console.log(arr, 'aa');
    return arr
  });
}

console.log(a([[1, 2, 3], [4, 5, 6], [7, 8, 9]]));
*另一种方法*
function get(array, index = 0, val = []) {
  let resultArr = [];
  if (!array[index]) {
    return [val]
  };
  //这里还需判段一下是否数组array[index]
  array[index].forEach((v, i) => {
    resultArr.push(...get(array, index + 1, index === 0 ? [v] : [...val, v]))
  })
  return resultArr
}
get([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);

12.盛最多水的容器:给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。说明:你不能倾斜容器。

/*
盛水最多就是找到坐标两两相乘,乘积最大的;例如`[1, 8, 6, 2, 5, 4, 8, 3, 7]`在初始时,左右指针分别指向数组的左右两端,它们可以容纳的水量为 \min(1, 7) * 8 = 8min(1,7)∗8=8。

此时我们需要移动一个指针。移动哪一个呢?直觉告诉我们,应该移动对应数字较小的那个指针(即此时的左指针)。这是因为,由于容纳的水量是由:
**(两个指针指向的数字中较小值 * 指针之间的距离)**
两个指针指向的数字中较小值∗指针之间的距离决定的。如果我们移动数字较大的那个指针,那么前者「两个指针指向的数字中较小值」不会增加,后者「指针之间的距离」会减小,那么这个乘积会减小。因此,我们移动数字较大的那个指针是不合理的。因此,我们移动 数字较小的那个指针。
*/

13.给定一个非负整数c,a平方+ b平方 = c 。求出a和b。

function sqrt(params) {
  var set = new Set()
  for (let i = 0; i ** 2 < params; i++) {
//Math.sqrt()返回一个数的平方根
    const a = Math.sqrt(params - i ** 2);
    aa = parseInt(a)
    if (Number.isInteger(a)) {
      set.add(i, a)
    }

  }
  return set
}
console.log(sqrt(10));

14.n皇后问题

function name(n) {
//创建二维数组
  const board = new Array(n);
  for (let i = 0; i < n; i++) {
    board[i] = new Array(n).fill('.');
  }
  /*检查是否符合条件的函数*/
  function isValid(row, col, chessboard, n) {
    // 检查列
    for (let i = 0; i < row; i++) { // 这是一个剪枝
      if (chessboard[i][col] == 'Q') {
        return false;
      }
    }
    // 检查 45度角是否有皇后
    for (let i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
      if (chessboard[i][j] == 'Q') {
        return false;
      }
    }
    // 检查 135度角是否有皇后
    for (let i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
      if (chessboard[i][j] == 'Q') {
        return false;
      }
    }
    return true;
  }
  let ans = []
  //递归
  function back(rows = 0, pa, res = []) {
    if (rows === n) {
      ans.push([...res])
      return
    }
    for (let col = 0; col < n; col++) {
      if (isValid(rows, col, pa, n)) {
        board[rows][col] = 'Q'
        res.push([rows, col])
        back(rows + 1, board, res)
        res.pop()
        board[rows][col] = '.'
      }
    }
  }
  back(0, board, res = [])
  return ans
}
console.log(name(4));

15.分割一个数组成为2个数组,如果2个数组的平均值都相等返回true。分析:长度为4的数组那它可以拆分为一个数组长度为1(2)和另一个length为4(3)的组合。列举出一半的组合,剩下的用原数组的和减去列举出数组的和就是另一个数组的和,再去求平均值比较。

let arr = [2, 3, 4, 5, 6]
let l = arr.length
let l2 = Math.floor(l / 2)
let res = []
/*可以找到数组排列组合*/
function name(arr, n = 1, left = [], m) {
    if (n == m) {
        res.push(left)
        return
    }
    for (let i = 0; i < arr.length; i++) {
        left.push(arr[i])
        name(arr.slice(i + 1, arr.length), n + 1, left.slice(), m)
        left.pop()
    }
}

for (let i = 1; i <= l2; i++) {
    name(arr, 1, [], i + 1)
}
console.log(
    res
);

16.,给定一个开始数字和结尾数字,使用递归进行这个范围内的求和。

let res = 0
function name(n = 0, t, p = 0) {
  if (n == t + 1) {
    return res = p
  }
  name(n + 1, t, p + n)
}
name(1, 100, 0)
console.log(res);//5050

17.给定一个数组,使用递归求和。

function sum2(arr) {
  function f(i) {
    return i >= arr.length ? 0 : arr[i] + f(i + 1)
  }
  return f(0)
}
console.log(sum2([1, 3]))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值