刷题不在多,需要举一反三

1. 两数之和

  1. // 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
  2. // 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
  3. /**
  4. * @param {number[]} nums
  5. * @param {number} target
  6. * @return {number[]}
  7. */
  8. var twoSum = function (nums, target) {
  9. for (let i = 0; i < nums.length; i++) {
  10. let result = target - nums[i];
  11. if (nums.lastIndexOf(result) !== -1 && nums.lastIndexOf(result) !== i) {
  12. return [i, nums.lastIndexOf(result)];
  13. }
  14. }
  15. };
  16. var twoSum = function (nums, target) {
  17. for (let i = 0; i < nums.length; i++) {
  18. let result = nums.lastIndexOf(target - nums[i]);
  19. if (result > i) {
  20. return [i, result];
  21. }
  22. }
  23. };
  24. var twoSum = function (nums, target) {
  25. for (let i = 0; i < nums.length - 1; i++) {
  26. for (let j = i + 1; j < nums.length; j++) {
  27. if (nums[i] + nums[j] === target) {
  28. return [i, j];
  29. }
  30. }
  31. }
  32. };
  33. var twoSum = function (nums, target) {
  34. let map = new Map();
  35. for (let i = 0; i < nums.length; i++) {
  36. let k = target - nums[i];
  37. if (map.has(k)) {
  38. return [map.get(k), i];
  39. }
  40. map.set(nums[i], i);
  41. }
  42. return [];
  43. };

2. 两数相加

  1. // 给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
  2. // 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
  3. // 您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
  4. /**
  5. * Definition for singly-linked list.
  6. * function ListNode(val) {
  7. * this.val = val;
  8. * this.next = null;
  9. * }
  10. */
  11. /**
  12. * @param {ListNode} l1
  13. * @param {ListNode} l2
  14. * @return {ListNode}
  15. */
  16. var addTwoNumbers = function (l1, l2) {
  17. let c = 0;
  18. let r = new ListNode();
  19. let p = r;
  20. let p1 = l1;
  21. let p2 = l2;
  22. while (p1 || p2 || c) {
  23. c += (p1 && p1.val) + (p2 && p2.val);
  24. p.next = new ListNode(c % 10);
  25. c = parseInt(c / 10);
  26. p1 && (p1 = p1.next);
  27. p2 && (p2 = p2.next);
  28. p = p.next;
  29. }
  30. return r.next;
  31. };

3. 无重复字符的最长子串

  1. // 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
  2. /**
  3. * @param {string} s
  4. * @return {number}
  5. */
  6. // var lengthOfLongestSubstring = function (s) {
  7. // let arr = [], max = 0;
  8. // for (let i = 0; i < s.length; i++) {
  9. // let index = arr.indexOf(s[i]);
  10. // if (index !== -1) {
  11. // arr.splice(0, index + 1);
  12. // }
  13. // arr.push(s.charAt(i));
  14. // max = Math.max(arr.length, max);
  15. // }
  16. // return max;
  17. // };
  18. var lengthOfLongestSubstring = function (s) {
  19. let index = 0, max = 0;
  20. for (let i = 0, j = 0; j < s.length; j++) {
  21. index = s.substring(i, j).indexOf(s[j]);
  22. if (index === -1) {
  23. max = Math.max(max, j - i + 1);
  24. } else {
  25. i = i + index + 1;
  26. }
  27. }
  28. return max;
  29. };

7. 整数反转

  1. // 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
  2. /**
  3. * @param {number} x
  4. * @return {number}
  5. */
  6. var reverse = function (x) {
  7. var result = 0;
  8. var sign = Math.sign(x);
  9. x = Math.abs(x);
  10. while (x != 0) {
  11. result = result * 10 + (x % 10);
  12. x = (x / 10) | 0;
  13. }
  14. if (result > 2147483647 || result < -2147483648) {
  15. return 0;
  16. }
  17. return sign * result;
  18. };

9. 回文数

  1. // 判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
  2. /**
  3. * @param {number} x
  4. * @return {boolean}
  5. */
  6. var isPalindrome = function (x) {
  7. return x.toString() === x.toString().split("").reverse().join("");
  8. };

13. 罗马数字转整数

  1. // 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
  2. // 字符 数值
  3. // I 1
  4. // V 5
  5. // X 10
  6. // L 50
  7. // C 100
  8. // D 500
  9. // M 1000
  10. // 例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
  11. // 通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
  12. // I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
  13. // X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
  14. // C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
  15. // 给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。
  16. /**
  17. * @param {string} s
  18. * @return {number}
  19. */
  20. var romanToInt = function (s) {
  21. const map = {
  22. I: 1,
  23. V: 5,
  24. X: 10,
  25. L: 50,
  26. C: 100,
  27. D: 500,
  28. M: 1000,
  29. };
  30. let req = 0;
  31. for (let i = 0; i < s.length; i++) {
  32. if (i < s.length && map[s[i]] < map[s[i + 1]]) {
  33. req -= map[s[i]];
  34. } else {
  35. req += map[s[i]];
  36. }
  37. }
  38. return req;
  39. };

17. 电话号码的字母组合

  1. // 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
  2. // 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
  3. /**
  4. * @param {string} digits
  5. * @return {string[]}
  6. */
  7. var letterCombinations = function (digits) {
  8. if (digits.length <= 0) return [];
  9. let map = ["", 1, "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"];
  10. let num = digits.split("");
  11. let code = [];
  12. num.forEach((item) => {
  13. if (map[item]) {
  14. code.push(map[item]);
  15. }
  16. });
  17. let comb = (arr) => {
  18. let tmp = [];
  19. if (arr.length == 1) {
  20. for (let i = 0; i < arr[0].length; i++) {
  21. tmp.push(arr[0][i]);
  22. }
  23. return tmp;
  24. } else {
  25. for (let i = 0; i < arr[0].length; i++) {
  26. for (let j = 0; j < arr[1].length; j++) {
  27. tmp.push(`${arr[0][i]}${arr[1][j]}`);
  28. }
  29. }
  30. arr.splice(0, 2, tmp);
  31. if (arr.length > 1) {
  32. comb(arr);
  33. } else {
  34. return tmp;
  35. }
  36. return arr[0];
  37. }
  38. };
  39. return comb(code);
  40. };

20.有效的括号

  1. /**
  2. * @param {string} s
  3. * @return {boolean}
  4. */
  5. var isValid = function (s) {
  6. let map = {
  7. '{': '}',
  8. '(': ')',
  9. '[': ']'
  10. };
  11. let stack = [];
  12. for (let i = 0; i < s.length; i++) {
  13. if (map[s[i]]) {
  14. stack.push(s[i]);
  15. } else if (s[i] !== map[stack.pop()]) {
  16. return false;
  17. }
  18. }
  19. return stack.length === 0;
  20. };
  21. /**
  22. * @param {string} s
  23. * @return {boolean}
  24. */
  25. let isValid = function (s) {
  26. let sl = s.length
  27. if (sl % 2 !== 0) return false
  28. let leftToRight = {
  29. "{": "}",
  30. "[": "]",
  31. "(": ")",
  32. }
  33. // 建立一个反向的 value -> key 映射表
  34. let rightToLeft = createReversedMap(leftToRight)
  35. // 用来匹配左右括号的栈
  36. let stack = []
  37. for (let i = 0; i < s.length; i++) {
  38. let bracket = s[i]
  39. // 左括号 放进栈中
  40. if (leftToRight[bracket]) {
  41. stack.push(bracket)
  42. } else {
  43. let needLeftBracket = rightToLeft[bracket]
  44. // 左右括号都不是 直接失败
  45. if (!needLeftBracket) {
  46. return false
  47. }
  48. // 栈中取出最后一个括号 如果不是需要的那个左括号 就失败
  49. let lastBracket = stack.pop()
  50. if (needLeftBracket !== lastBracket) {
  51. return false
  52. }
  53. }
  54. }
  55. if (stack.length) {
  56. return false
  57. }
  58. return true
  59. }
  60. function createReversedMap(map) {
  61. return Object.keys(map).reduce((prev, key) => {
  62. const value = map[key]
  63. prev[value] = key
  64. return prev
  65. }, {})
  66. }

21. 合并两个有序链表

  1. // 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
  2. /**
  3. * Definition for singly-linked list.
  4. * function ListNode(val) {
  5. * this.val = val;
  6. * this.next = null;
  7. * }
  8. */
  9. /**
  10. * @param {ListNode} l1
  11. * @param {ListNode} l2
  12. * @return {ListNode}
  13. */
  14. var mergeTwoLists = function (l1, l2) {
  15. if (l1 === null) return l2;
  16. let cur = l1;
  17. while (l2) {
  18. let node = new ListNode();
  19. if (cur.val >= l2.val) {
  20. node.val = cur.val;
  21. node.next = cur.next;
  22. cur.val = l2.val;
  23. cur.next = node;
  24. l2 = l2.next;
  25. } else if (cur.next && l2.val <= cur.next.val) {
  26. node.val = l2.val;
  27. node.next = cur.next;
  28. cur.next = node;
  29. l2 = l2.next;
  30. } else if (!cur.next) {
  31. node.val = l2.val;
  32. node.next = null;
  33. cur.next = node;
  34. l2 = l2.next;
  35. continue;
  36. }
  37. cur = cur.next;
  38. }
  39. return l1;
  40. };

89. 格雷编码

  1. // 格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异。
  2. // 给定一个代表编码总位数的非负整数 n,打印其格雷编码序列。即使有多个不同答案,你也只需要返回其中一种。
  3. // 格雷编码序列必须以 0 开头。
  4. /**
  5. * @param {number} n
  6. * @return {number[]}
  7. */
  8. var grayCode = function (n) {
  9. let make = (n) => {
  10. if (n === 1) {
  11. return ["0", "1"];
  12. } else {
  13. let prev = make(n - 1);
  14. let result = [];
  15. let max = Math.pow(2, n) - 1;
  16. for (let i = 0; i < prev.length; i++) {
  17. result[i] = `0${prev[i]}`;
  18. result[max - i] = `1${prev[i]}`;
  19. }
  20. return result;
  21. }
  22. };
  23. return make(n);
  24. };
  25. var grayCode = function (n) {
  26. let make = (n) => {
  27. if (n === 1) return [0, 1];
  28. let result = make(n - 1);
  29. let highBit = 1 << (n - 1);
  30. for (let i = result.length - 1; i >= 0; i--) {
  31. result.push(result[i] + highBit);
  32. }
  33. return result;
  34. };
  35. if (n === 0) return [0];
  36. return make(n);
  37. };
  38. var grayCode = function (n) {
  39. let res = [0];
  40. for (let i = 0; i < n; i++) {
  41. res = res.concat(res.map((item) => (1 << i) + item).reverse());
  42. }
  43. return res;
  44. };

164. 最大间距

给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。
如果数组元素个数小于 2,则返回 0。
示例 1:
输入: [3,6,9,1]
输出: 3
解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。
示例 2:
输入: [10]
输出: 0
解释: 数组元素个数小于 2,因此返回 0。

  1. /**
  2. * @param {number[]} nums
  3. * @return {number}
  4. */
  5. var maximumGap = function (nums) {
  6. if (nums.length < 2) return 0;
  7. nums.sort((a, b) => a - b);
  8. // 保存相邻元素的最大差值
  9. let max = 0;
  10. let temp = [];
  11. for (let i = 0; i < nums.length - 1; i++) {
  12. temp = nums[i + 1] - nums[i];
  13. if (temp > max) {
  14. max = temp;
  15. }
  16. }
  17. return max;
  18. };

258. 各位相加

  1. // 给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。
  2. /**
  3. * @param {number} num
  4. * @return {number}
  5. */
  6. var addDigits = function (num) {
  7. let arr = [];
  8. for (let index of num.toString()) {
  9. arr.push(index);
  10. }
  11. if (arr.length === 1) {
  12. return parseInt(arr[0]);
  13. }
  14. let number = 0;
  15. for (let i = 0; i < arr.length; i++) {
  16. number += parseInt(arr[i]);
  17. }
  18. if (number > 9) {
  19. return addDigits(number);
  20. } else {
  21. return number;
  22. }
  23. };

349. 两个数组的交

  1. // 给定两个数组,编写一个函数来计算它们的交集。
  2. /**
  3. * @param {number[]} nums1
  4. * @param {number[]} nums2
  5. * @return {number[]}
  6. */
  7. var intersection = function (nums1, nums2) {
  8. let arr1 = Array.from(new Set(nums1));
  9. let arr2 = Array.from(new Set(nums2));
  10. let arr3 = new Array();
  11. for (let [v, k] of arr1.entries()) {
  12. if (arr2.includes(k)) {
  13. arr3.push(k);
  14. }
  15. }
  16. return arr3;
  17. };
  18. var intersection = function (...arrs) {
  19. let res = arrs[0];
  20. for (let i = 1; i < arrs.length; i++) {
  21. res = res.filter((item) => arrs[i].includes(item));
  22. }
  23. return [...new Set(res)];
  24. };

605. 种花问题

  1. // 605. 种花问题
  2. // 假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
  3. // 给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花),和一个数 n 。能否在不打破种植规则的情况下种入 n 朵花?能则返回True,不能则返回False。
  4. /**
  5. * @param {number[]} flowerbed
  6. * @param {number} n
  7. * @return {boolean}
  8. */
  9. var canPlaceFlowers = function (flowerbed, n) {
  10. let max = 0;
  11. for (let i = 0; i < flowerbed.length - 1; i++) {
  12. if (flowerbed[i] === 0) {
  13. if (i === 0 && flowerbed[1] === 0) {
  14. max++;
  15. i++;
  16. } else if (flowerbed[i - 1] === 0 && flowerbed[i + 1] === 0) {
  17. max++;
  18. i++;
  19. }
  20. }
  21. }
  22. return max >= n;
  23. };
  24. // var canPlaceFlowers = function (flowerbed, n) {
  25. // let count = 1, sum = 0;
  26. // for (val of flowerbed) {
  27. // if (val == 1) {
  28. // if (count > 1) sum += Math.floor((count - 1) / 2);
  29. // count = 0;
  30. // } else {
  31. // count++;
  32. // }
  33. // }
  34. // if (count > 1) sum += Math.floor(count / 2);
  35. // return sum >= n;
  36. // };

914. 卡牌分组

  1. // 给定一副牌,每张牌上都写着一个整数。
  2. // 此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组:
  3. // 每组都有 X 张牌。
  4. // 组内所有的牌上都写着相同的整数。
  5. // 仅当你可选的 X >= 2 时返回 true。
  6. /**
  7. * @param {number[]} deck
  8. * @return {boolean}
  9. */
  10. var hasGroupsSizeX = function (deck) {
  11. if (deck.length <= 1) return false;
  12. deck.sort((a, b) => {
  13. a - b;
  14. });
  15. let min = Number.MAX_SAFE_INTEGER;
  16. let dst = [];
  17. let result = true;
  18. let tmp = [];
  19. for (let i = 0; i < deck.length; i++) {
  20. tmp.push(deck[i]);
  21. for (let j = i + 1; j < deck.length - 1; j++) {
  22. if (deck[i] === deck[j]) {
  23. tmp.push(deck[j]);
  24. } else {
  25. if (min > tmp.length) {
  26. min = tmp.length;
  27. }
  28. dst.push([].concat(tmp));
  29. tmp.length = 0;
  30. i = j;
  31. break;
  32. }
  33. }
  34. }
  35. dst.every((item) => {
  36. if (item.length % min !== 0) {
  37. result = false;
  38. return false;
  39. }
  40. });
  41. return result;
  42. };
  43. var hasGroupsSizeX = function (deck) {
  44. // 最大公约数计算公式
  45. function gcd(num1, num2) {
  46. // 利用辗转相除法来计算最大公约数
  47. return num2 === 0 ? num1 : gcd(num2, num1 % num2);
  48. }
  49. // 相同牌出现次数Map
  50. let timeMap = new Map();
  51. // 遍历牌
  52. deck.forEach((num) => {
  53. // 统计每张牌出现的次数
  54. timeMap.set(num, timeMap.has(num) ? timeMap.get(num) + 1 : 1);
  55. });
  56. // Map.protype.values()返回的是一个新的Iterator对象,所以可以使用扩展运算符(...)来构造成数组
  57. let timeAry = [...timeMap.values()];
  58. /*
  59. 最大公约数
  60. 因为该数组是出现次数数组,最小值至少为1(至少出现1次),所以默认赋值为数组首位对公约数计算无干扰
  61. */
  62. let g = timeAry[0];
  63. // 遍历出现次数,计算最大公约数
  64. timeAry.forEach((time) => {
  65. // 因为需要比较所有牌出现次数的最大公约数,故需要一个中间值
  66. g = gcd(g, time);
  67. });
  68. // 判断是否满足题意
  69. return g >= 2;
  70. };

1047. 删除字符串中的所有相邻重复项

  1. // 给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
  2. // 在 S 上反复执行重复项删除操作,直到无法继续删除。
  3. // 在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
  4. /**
  5. * @param {string} S
  6. * @return {string}
  7. */
  8. var removeDuplicates = function (S) {
  9. let stack = [];
  10. for (const c of S) {
  11. let prev = stack.pop();
  12. if (prev !== c) {
  13. stack.push(prev);
  14. stack.push(c);
  15. }
  16. }
  17. return stack.join("");
  18. };

1209. 删除字符串中的所有相邻重复项 II

  1. // 给你一个字符串 s,「k 倍重复项删除操作」将会从 s 中选择 k 个相邻且相等的字母,并删除它们,使被删去的字符串的左侧和右侧连在一起。
  2. // 你需要对 s 重复进行无限次这样的删除操作,直到无法继续为止。
  3. // 在执行完所有删除操作后,返回最终得到的字符串。
  4. /**
  5. * @param {string} s
  6. * @param {number} k
  7. * @return {string}
  8. */
  9. var removeDuplicates = function (s, k) {
  10. let stack = [];
  11. for (const c of s) {
  12. let prev = stack.pop();
  13. if (!prev || prev[0] !== c) {
  14. stack.push(prev);
  15. stack.push(c);
  16. } else if (prev.length < k - 1) {
  17. stack.push(prev + c);
  18. }
  19. }
  20. return stack.join("");
  21. };

1295. 统计位数为偶数的数字

  1. // 给你一个整数数组 nums,
  2. // 请你返回其中位数为 偶数 的数字的个数。
  3. // 示例 1:
  4. // 输入:nums = [12,345,2,6,7896]
  5. // 输出:2
  6. // 解释:
  7. // 12 是 2 位数字(位数为偶数)
  8. // 345 是 3 位数字(位数为奇数)
  9. // 2 是 1 位数字(位数为奇数)
  10. // 6 是 1 位数字 位数为奇数)
  11. // 7896 是 4 位数字(位数为偶数)
  12. // 因此只有 12 和 7896 是位数为偶数的数字
  13. // 示例 2:
  14. // 输入:nums = [555,901,482,1771]
  15. // 输出:1
  16. // 解释:
  17. // 只有 1771 是位数为偶数的数字。
  18. // 提示:
  19. // 1 <= nums.length <= 500
  20. // 1 <= nums[i] <= 10^5
  21. /**
  22. * @param {number[]} nums
  23. * @return {number}
  24. */
  25. var findNumbers = function (nums) {
  26. let time = 0;
  27. for (let i = 0; i < nums.length; i++) {
  28. if (String(nums[i]).length % 2 === 0) {
  29. time++;
  30. }
  31. }
  32. return time;
  33. };
  34. const findNumbers = (nums) => nums.reduce((prev, next) => prev + (String(next).length % 2 === 0 ? 1 : 0), 0);

1313. 解压缩编码列表

  1. // 给你一个以行程长度编码压缩的整数列表 nums 。
  2. // 考虑每对相邻的两个元素 [freq, val] = [nums[2*i], nums[2*i+1]] (其中 i >= 0 ),每一对都表示解压后子列表中有 freq 个值为 val 的元素,你需要从左到右连接所有子列表以生成解压后的列表。
  3. // 请你返回解压后的列表。
  4. /**
  5. * @param {number[]} nums
  6. * @return {number[]}
  7. */
  8. var decompressRLElist = function (nums) {
  9. const result = [];
  10. for (let i = 1; i < nums.length; i++) {
  11. if (i % 2 === 1) {
  12. result.push(...Array.from(Array(nums[i - 1]), () => nums[i]));
  13. }
  14. }
  15. return result;
  16. };

1317. 将整数转换为两个无零整数的和

  1. // 「无零整数」是十进制表示中 不含任何 0 的正整数。
  2. // 给你一个整数 n,请你返回一个 由两个整数组成的列表 [A, B],满足:
  3. // A 和 B 都是无零整数
  4. // A + B = n
  5. // 题目数据保证至少有一个有效的解决方案。
  6. // 如果存在多个有效解决方案,你可以返回其中任意一个。
  7. /**
  8. * @param {number} n
  9. * @return {number[]}
  10. */
  11. var getNoZeroIntegers = function (n) {
  12. let time = 1;
  13. while (String(time).includes("0") || String(n - time).includes("0")) {
  14. time++;
  15. }
  16. return [time, n - time];
  17. };

剑指 Offer 11. 旋转数组的最小数字

  1. // 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。
  2. /**
  3. * @param {number[]} numbers
  4. * @return {number}
  5. */
  6. // var minArray = function (numbers) {
  7. // for (let i = 0; i < numbers.length; i++) {
  8. // if (numbers[i + 1] < numbers[i]) {
  9. // return numbers[i + 1];
  10. // }
  11. // }
  12. // return numbers[0];
  13. // };
  14. var minArray = function (numbers) {
  15. let i = 0, j = numbers.length - 1;
  16. while (i < j) {
  17. const m = Math.floor((i + j) / 2);
  18. if (numbers[m] > numbers[j]) {
  19. i = m + 1;
  20. } else if (numbers[m] < numbers[j]) {
  21. j = m;
  22. } else {
  23. j--;
  24. }
  25. }
  26. return numbers[i];
  27. };