返回

深入剖析TypeScript算法题实战,解码编程难题之秘

前端

前言:踏上算法题实战征程

算法题实战是程序员提升技能、检验知识的有效途径。在本文中,我们将使用TypeScript来解决剑指offer的算法题。这些问题涵盖了各种各样的主题,包括数组、字符串、链表、树、排序和搜索等。通过解决这些问题,我们将加深对TypeScript的理解,并提升我们的编程技巧。

TypeScript算法题实战之旅

1. 圆圈中最后剩下的数字

题目:

给出包含n个数字的圆圈,从数字0开始,每次从圆圈中删除第m个数字,然后从下一个数字继续删除,直到圈中只剩下一个数字。求最后剩下的数字。

解答:

function lastRemaining(n: number, m: number): number {
  if (n < 1 || m < 1) {
    throw new Error("Invalid input parameters.");
  }

  let arr = new Array(n);
  for (let i = 0; i < n; i++) {
    arr[i] = i;
  }

  let index = 0;
  while (arr.length > 1) {
    index = (index + m - 1) % arr.length;
    arr.splice(index, 1);
  }

  return arr[0];
}

2. 机器人的运动范围

题目:

在一个m×n的网格中,机器人从(0, 0)出发,只能向右或向下走,不能走回头路。如果机器人能够到达网格中的某个格子,则该格子被称为机器人的运动范围。求机器人的运动范围。

解答:

function robotMove(m: number, n: number): number {
  if (m <= 0 || n <= 0) {
    return 0;
  }

  let visited = new Array(m).fill(false).map(() => new Array(n).fill(false));
  let count = 0;

  function dfs(x: number, y: number): void {
    if (x < 0 || x >= m || y < 0 || y >= n || visited[x][y] || !validSum(x, y)) {
      return;
    }

    visited[x][y] = true;
    count++;

    dfs(x + 1, y);
    dfs(x - 1, y);
    dfs(x, y + 1);
    dfs(x, y - 1);
  }

  function validSum(x: number, y: number): boolean {
    let sum = 0;
    while (x > 0) {
      sum += x % 10;
      x = Math.floor(x / 10);
    }
    while (y > 0) {
      sum += y % 10;
      y = Math.floor(y / 10);
    }
    return sum <= 9;
  }

  dfs(0, 0);

  return count;
}

3. 二叉搜索树的最近公共祖先

题目:

给定一个二叉搜索树,求两个给定节点的最近公共祖先。

解答:

class TreeNode {
  val: number;
  left: TreeNode | null;
  right: TreeNode | null;

  constructor(val: number) {
    this.val = val;
    this.left = null;
    this.right = null;
  }
}

function lowestCommonAncestor(root: TreeNode | null, p: TreeNode, q: TreeNode): TreeNode | null {
  if (!root || root === p || root === q) {
    return root;
  }

  let left = lowestCommonAncestor(root.left, p, q);
  let right = lowestCommonAncestor(root.right, p, q);

  if (left && right) {
    return root;
  } else if (left) {
    return left;
  } else if (right) {
    return right;
  } else {
    return null;
  }
}

4. 构建乘积数组

题目:

给定一个长度为n的数组,构建一个长度也为n的数组,其中每个元素是原数组中除该元素外的所有元素的乘积。

解答:

function productExceptSelf(nums: number[]): number[] {
  if (nums === null || nums.length === 0) {
    return [];
  }

  let n = nums.length;
  let result = new Array(n).fill(1);

  let prefix = 1;
  for (let i = 0; i < n; i++) {
    result[i] *= prefix;
    prefix *= nums[i];
  }

  let suffix = 1;
  for (let i = n - 1; i >= 0; i--) {
    result[i] *= suffix;
    suffix *= nums[i];
  }

  return result;
}

5. 不用加减乘除做加法

题目:

不使用加减乘除运算符,实现两个非负整数的加法。

解答:

function addWithoutArithmetic(a: number, b: number): number {
  if (a === 0) {
    return b;
  }
  if (b === 0) {
    return a;
  }

  while (b > 0) {
    let carry = a & b;
    a ^= b;
    b = carry << 1;
  }

  return a;
}

6. 股票的最大利润

题目:

给定一个数组prices,其中prices[i]是某支股票第i天的价格。求在不