算法初级
有些根据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]))