这类题目算不上算法,是在看对 js 语言能力的高低。

一. 数

1. 不借助临时变量交换两个数?

实现交换仍然需要临时变量,这个临时变量只能有 a b 承担,且 要不是 “和” 要不是 “差”,这种不变的东西。

  1. // 如:
  2. let a = 2;
  3. let b = 4;
  4. // 方法1:
  5. a = a + b; // a 被看做临时变量,存两者之和
  6. b = a - b;
  7. a = a - b;
  8. // 方法2:
  9. a = a - b; // a 被看做临时变量,存两者之差
  10. b = b + a;
  11. a = b - a;

当时,自己一口气就写出来了,还是挺给人自信的。
今天再看犀牛书的时候,还看到一种更狠的:

  1. let a = 2;
  2. let b = 4;
  3. [a, b] = [b, a];

2. 一个数组中的最大最小数之差

寻找一个数组中的最大值,基本语言能力。

  1. function getDiff(list) {
  2. let min = list[0];
  3. let max = list[0];
  4. for (let i = 0; i < list.length; i ++) {
  5. let item = list[i];
  6. if (min > item) {
  7. min = item;
  8. } else if (max <= item) {
  9. max = item;
  10. }
  11. }
  12. return max - min;
  13. }
  14. let list = [4, 5, 8, 3, 9];
  15. console.log('最大差为:', getDiff(list));

再给一个简单的版本:

  1. let max = tt[0], min = tt[0];
  2. for (let v of tt) {
  3. if (v > max) {
  4. max = v;
  5. }
  6. if (v < min) {
  7. min = v;
  8. }
  9. }

3. 大数相加

(钉钉的笔试题)

  1. function add(x, y) {
  2. if (!(/^\d*$/.test(x) && /^\d*$/.test(y))) {
  3. return;
  4. }
  5. const x_arr = x.split('');
  6. const y_arr = y.split('');
  7. // 补齐位数
  8. if (x_arr.length > y_arr.length) {
  9. let more = x_arr.length - y_arr.length;
  10. for (let i = 0; i < more; i++) {
  11. y_arr.unshift(0);
  12. }
  13. }
  14. if (x_arr.length < y_arr.length) {
  15. let more = y_arr.length - x_arr.length;
  16. for (let i = 0; i < more; i++) {
  17. x_arr.unshift(0);
  18. }
  19. }
  20. let needAdd = 0;
  21. let resultArr = [];
  22. for (let i = x_arr.length - 1; i >= 0; i--) {
  23. let p = parseInt(x_arr[i]);
  24. let q = parseInt(y_arr[i]);
  25. let sum = p + q + parseInt(needAdd) + ''; // 数字转字符串
  26. sum = sum.split('');
  27. resultArr.unshift(sum.pop());
  28. needAdd = sum.pop() || 0; // 没有进位,默认为0
  29. }
  30. if (parseInt(needAdd) === 1) {
  31. resultArr.unshift(1);
  32. }
  33. return resultArr.join('');
  34. }
  35. console.log(add('1', '2'));
  36. console.log(add('9', '2'));
  37. console.log(add('10', '11'));
  38. console.log(add('10', '999'));
  39. console.log(add('1', '999'));
  40. console.log(add("11111111111111111111", "22222222222222222222"));

写的是什么玩意,这么复杂,

  1. function add(x, y) {
  2. let naughtyBoy = 0;
  3. let add1 = x.split('').reverse();
  4. let add2 = y.split('').reverse();
  5. let sum = [];
  6. // 假设 add1 比较长
  7. for (let i = 0; i < add1.length; i++) {
  8. let _sum = Number(add1[i]) + Number(add2[i]) + naughtyBoy;
  9. if (_sum < 10) {
  10. sum[i] = _sum;
  11. naughtyBoy = 0;
  12. } else {
  13. sum[i] = _sum - 10; // 取个位
  14. naughtyBoy = 1;
  15. }
  16. }
  17. return sum.reverse().join('');
  18. }

4.版本号对比

(钉钉的笔试题)

  1. function compareVersion(v1, v2) {
  2. if ((typeof v1 !== 'string') || (typeof v2 !== 'string')) {
  3. return;
  4. }
  5. let version1_arr = v1.trim().split('.');
  6. let version2_arr = v2.trim().split('.');
  7. // 补齐位数
  8. if (version1_arr.length > version2_arr.length) {
  9. const more = version1_arr.length - version2_arr.length;
  10. for (let i = 0; i < more; i++) {
  11. version2_arr.push(0);
  12. }
  13. }
  14. if (version1_arr.length < version2_arr.length) {
  15. const more = version2_arr.length - version1_arr.length;
  16. for (let i = 0; i < more; i++) {
  17. version1_arr.push(0);
  18. }
  19. }
  20. for (let i = 0; i < version1_arr.length; i++) {
  21. let _v1 = parseInt(version1_arr[i]);
  22. let _v2 = parseInt(version2_arr[i]);
  23. if (_v1 > _v2) {
  24. return 1;
  25. } else if (_v1 < _v2) {
  26. return -1;
  27. } else {
  28. continue;
  29. }
  30. }
  31. return 0;
  32. }
  33. console.log(compareVersion('1.2', '1.2.0'))
  34. console.log(compareVersion('13.37', '1.2 '));
  35. console.log(compareVersion('0.1', '1.1.1'));

5. 数组去重,以及统计一组数中重复数量最多的字符。

6. 二分查找有序数组(数组顺序从小到大)

  1. let pos = 0;
  2. function binarySearch(target, arr) { // 我们平时不会用这个方法,但是这个思想应该知道
  3. let midPos = arr.length >>> 1;
  4. let mid = arr[midPos];
  5. if (target === mid) {
  6. return pos + midPos;
  7. } else if (target > mid) {
  8. pos = pos + midPos;
  9. return binarySearch(target, arr.slice(midPos));
  10. } else {
  11. return binarySearch(target, arr.slice(0, midPos));
  12. }
  13. }
  14. let arr = [1,2,4,6,8,9,11,34,67];
  15. let target = 11;
  16. console.log(`数组${JSON.stringify(arr)}中${target}的位置:`, binarySearch(target, arr));

算法更高级些:

  1. function find(arr, target, initalIndex) {
  2. const midIndex = Math.floor(arr.length / 2);
  3. const midValue = arr[midIndex];
  4. if (target === midValue) {
  5. return midIndex + initalIndex;
  6. } else if (target < midValue) {
  7. return find(arr.slice(0, midIndex), target, 0);
  8. } else {
  9. return find(arr.slice(midIndex), target, midIndex);
  10. }
  11. }

二. 字符操作

1. 生成指定长度的随机字符串

: 属于 对 math api 的熟悉,本身算法的感觉不强

  1. function randomString(length, chars) {
  2. var result = '';
  3. for (var i = length; i > 0; --i) {
  4. result += chars[Math.floor(Math.random() * chars.length)]
  5. };
  6. return result;
  7. }
  8. var rString = randomString(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');

2. 字符串查找

:请使用最基本的遍历来实现判断字符串 a 是否被包含在字符串 b 中,并返回第一次出现的位置

  1. function includes(source, target) { // source 是否包含 target 字符串
  2. // 'dog' 包含于 'mydogismine'
  3. for (let i = 0; i < source.length; i++) {
  4. let _source = source.slice(i);
  5. if (_isSameString(_source, target)) {
  6. return true;
  7. }
  8. }
  9. }
  10. function _isSameString(source, target) {
  11. let clipedSouce = source.slice(0, target.length); // 截取相同长度进行对比
  12. return clipedSouce === target;
  13. }
  14. console.log('mydogismine 包含 dog 吗?', includes('mydogismine', 'dog'));
  15. console.log('mydogismine 包含 dog 吗?', includes('mydogismine', 'dogs'));

简单点:

  1. var x = 'abc';
  2. var y = 'sdfsfdfsabcdsfsdfabc';
  3. function find(target, source) {
  4. const targetLength = target.length;
  5. for (let i = 0; i < source.length; i++) {
  6. if (target === source.slice(i, i + targetLength)) {
  7. return i;
  8. }
  9. }
  10. }
  11. find(x, y);

3. 判断一个单词是否有回文

考点:去复习下 数组 的常见 api,如 reverse reduce 等等,另外由此扩展 其他 js api 的使用。

4. 字符串中出现的不重复的最长长度

我写的第一版 是根据调试写出来的,所以在思路上并成熟,它不是先由好的思路发展而来:

  1. // 字符串出现的不重复最长长度
  2. function getLength(str) {
  3. let resultMap = [];
  4. let stack = [];
  5. let i = 0;
  6. let pre;
  7. while(i <= str.length) {
  8. if (str[i] !== pre) {
  9. if (i === str.length) {
  10. resultMap.push(stack.join(''));
  11. stack = [];
  12. } else {
  13. stack.push(str[i]);
  14. }
  15. } else {
  16. if (stack.length > 0) {
  17. resultMap.push(stack.join(''));
  18. stack = [];
  19. }
  20. }
  21. pre = str[i];
  22. i++;
  23. }
  24. return resultMap;
  25. }
  26. console.log(getLength('abcckkldk'));