【华为OD 考试 js常规算法题 练习题 汇总学习】

js常规算法题

由于在工作中有很多常用计算方法无法记住,每次都是在使用到的时候去搜索,为了加深记忆,在工作之余去牛客网做华为机试练习题,这里记录部分练习结果:

字符串逆序
描述
将一个字符串内容颠倒过来,并输出。
数据范围:1≤len(str)≤10000 ;
  1. 方法1 使用数组的reverse();
const strReverse1 = (str: string) => {
    if(!str || str.length > 1000) console.log('请输入正确字符!')
    const newArr = Array.from(str);
    return newArr.reverse().join('')

}
  1. 方法2 使用的也是数组的reverse() 方法,先将字符串变为数组;str.split()
const strReverse2 = (str: string) => {
    if(!str || str.length > 1000) console.log('请输入正确字符!')
    const newArr = Array.from(str);
    retrun newArr.reverse().join('')

}
  1. 方法3 使用遍历方法 使用字符串 charAt() 方法 反正指定位置字符串
const strReverse3 = (str: string) => {
	let newStr = ''
	for(let i = str.length-1; i > 0; i ++){
		newStr += str.charAt(i)
	}
	retrun newStr
}
求解立方根
描述

计算一个浮点数的立方根,不要使用库函数。
保留一位小数

这里常规解题时我们会使用 js Match库函数 cbrt() 函数很方便就计算出来了,但是题目要求不能使用库函数;

四则运算
描述

输入一个表达式(用字符串表示),求这个表达式的值。
保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法

实现方式:

1、解释说明:
这个问题可以通过Python的内置函数eval()来解决。eval()函数用来执行一个字符串表达式,并返回表达式的值。在这个问题中,我们需要将输入的字符串表达式传递给eval()函数,然后返回计算结果。

2、使用示例:

expression = "1 + 2 * (3 - 4) / 5"
result = eval(expression)
print(result)

在这个示例中,我们定义了一个字符串表达式"1 + 2 * (3 - 4) / 5",然后使用eval()函数计算这个表达式的值,并将结果打印出来。

3、注意事项:
在使用eval()函数时,需要确保输入的字符串表达式是合法的,否则会抛出异常。此外,由于eval()函数可以执行任何Python代码,因此在处理用户输入时需要特别小心,以防止恶意代码的执行。

素数伴侣

描述

若两个正整数的和为素数,则这两个正整数称之为“素数伴侣”,如2和5、6和13,它们能应用于通信加密。现在密码学会请你设计一个程序,从已有的 N ( N 为偶数)个正整数中挑选出若干对组成“素数伴侣”,挑选方案多种多样,例如有4个正整数:2,5,6,13,如果将5和6分为一组中只能得到一组“素数伴侣”,而将2和5、6和13编组将得到两组“素数伴侣”,能组成“素数伴侣”最多的方案称为“最佳方案”,当然密码学会希望你寻找出“最佳方案”。

输入:

有一个正偶数 n ,表示待挑选的自然数的个数。后面给出 n 个具体的数字。

输出:

输出一个整数 K ,表示你求得的“最佳方案”组成“素数伴侣”的对数。

实现方式:

1、解释说明:
这个问题可以通过动态规划来解决。首先,我们需要一个函数来判断一个数是否为素数。然后,我们需要一个二维数组dp,其中dp[i][j]表示前i个数中选择j对的“最佳方案”组成“素数伴侣”的对数。我们可以通过遍历所有的数,对于每一个数,我们都有两种选择,一种是选择它作为一对中的其中一个数,另一种是不选择它。如果我们选择了它,那么我们需要在前i-1个数中选择j-1对,这可以通过dp[i-1][j-1]来得到。如果我们不选择它,那么我们需要在前i-1个数中选择j对,这可以通过dp[i-1][j]来得到。最后,我们需要在所有的选择中找出最大的那个,这就是我们的“最佳方案”。

2、使用示例:
假设我们有4个正整数:2,5,6,13,我们可以使用以下代码来找出“最佳方案”:

def is_prime(n):
    if n < 2:
        return False
    for i in range(2, int(n**0.5)+1):
        if n % i == 0:
            return False
    return True

def best_plan(n, nums):
    dp = [[0 for _ in range(n//2+1)] for _ in range(n+1)]
    for i in range(1, n+1):
        for j in range(1, n//2+1):
            if is_prime(nums[i-1] + nums[j-1]):
                dp[i][j] = max(dp[i-1][j-1]+1, dp[i-1][j])
            else:
                dp[i][j] = dp[i-1][j]
    return dp[n][n//2]

nums = [2, 5, 6, 13]
print(best_plan(len(nums), nums))

3、注意事项:
这个问题的时间复杂度是O(n2),空间复杂度也是O(n2),所以当n非常大的时候,可能会导致运行时间过长或者内存不足。在实际使用时,需要考虑到这一点。

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

这是一个常见的编程问题,我们可以通过模拟螺旋路径的方式来解决这个问题。具体步骤如下:

  1. 初始化一个空列表 result 用于存储结果。
  2. 定义四个边界值,分别是 top、bottom、left、right,分别表示矩阵的上、下、左、右边界。
  3. 使用一个 while 循环,当 top <= bottom 且 left <= right 时,执行以下操作:
    • 从左到右遍历上边界的元素,将元素添加到 result 中,然后将 top 加 1。
    • 从上到下遍历右边界的元素,将元素添加到 result 中,然后将 right 减 1。
    • 如果 top <= bottom,那么从右到左遍历下边界的元素,将元素添加到 result 中,然后将 bottom 减 1。
    • 如果 left <= right,那么从下到上遍历左边界的元素,将元素添加到 result 中,然后将 left 加 1。
  4. 返回 result。

以下是 Python 代码实现:

def spiralOrder(matrix):
    if not matrix: return []
    result = []
    top, bottom, left, right = 0, len(matrix) - 1, 0, len(matrix[0]) - 1
    while top <= bottom and left <= right:
        for i in range(left, right + 1):
            result.append(matrix[top][i])
        top += 1
        for i in range(top, bottom + 1):
            result.append(matrix[i][right])
        right -= 1
        if top <= bottom:
            for i in range(right, left - 1, -1):
                result.append(matrix[bottom][i])
            bottom -= 1
        if left <= right:
            for i in range(bottom, top - 1, -1):
                result.append(matrix[i][left])
            left += 1
    return result

这个函数接受一个二维列表 matrix 作为输入,返回一个包含 matrix 中所有元素的列表,元素的顺序是按照顺时针螺旋顺序排列的。

以下是 js 代码实现:

function spiralOrder(matrix) {
  if (!matrix || matrix.length === 0) return [];

  let result = [];
  let rowStart = 0;
  let rowEnd = matrix.length - 1;
  let colStart = 0;
  let colEnd = matrix[0].length - 1;

  while (rowStart <= rowEnd && colStart <= colEnd) {
    // 从左到右遍历上边界
    for (let i = colStart; i <= colEnd; i++) {
      result.push(matrix[rowStart][i]);
    }
    rowStart++;

    // 从上到下遍历右边界
    for (let i = rowStart; i <= rowEnd; i++) {
      result.push(matrix[i][colEnd]);
    }
    colEnd--;

    // 从右到左遍历下边界
    if (rowStart <= rowEnd) {
      for (let i = colEnd; i >= colStart; i--) {
        result.push(matrix[rowEnd][i]);
      }
      rowEnd--;
    }

    // 从下到上遍历左边界
    if (colStart <= colEnd) {
      for (let i = rowEnd; i >= rowStart; i--) {
        result.push(matrix[i][colStart]);
      }
      colStart++;
    }
  }

  return result;
}

生命游戏

给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态: 1 即为 活细胞 (live),或 0 即为 死细胞 (dead)。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:

如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
如果死细胞周围正好有三个活细胞,则该位置死细胞复活;

这是一个经典的编程问题,被称为"生命游戏"。我们可以使用JavaScript来实现这个游戏的规则。以下是一个简单的实现:

function gameOfLife(board) {
    const m = board.length;
    const n = board[0].length;
    const dx = [-1, -1, -1, 0, 0, 1, 1, 1];
    const dy = [-1, 0, 1, -1, 1, -1, 0, 1];
    const copyBoard = JSON.parse(JSON.stringify(board));

    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            let liveNeighbors = 0;
            for (let k = 0; k < 8; k++) {
                const x = i + dx[k];
                const y = j + dy[k];
                if (x >= 0 && x < m && y >= 0 && y < n && copyBoard[x][y] === 1) {
                    liveNeighbors++;
                }
            }
            if (copyBoard[i][j] === 1 && (liveNeighbors < 2 || liveNeighbors > 3)) {
                board[i][j] = 0;
            } else if (copyBoard[i][j] === 0 && liveNeighbors === 3) {
                board[i][j] = 1;
            }
        }
    }
    return board;
}

这个函数接受一个二维数组board作为输入,表示面板的初始状态。然后,它创建了一个copyBoard来保存面板的初始状态,以便我们可以在不改变原始面板的情况下计算每个细胞的新状态。

对于面板上的每个细胞,我们计算其周围八个位置的活细胞数。如果一个活细胞周围活细胞数少于两个或多于三个,那么它将死亡(即变为死细胞)。如果一个死细胞周围正好有三个活细胞,那么它将复活(即变为活细胞)。

最后,我们返回更新后的面板。

旋转图像

给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

要实现旋转图像,我们可以先将矩阵进行转置,然后将每一行进行翻转。这里是一个使用JavaScript实现的示例代码:

function rotate(matrix) {
  const n = matrix.length;

  // 转置矩阵
  for (let i = 0; i < n; i++) {
    for (let j = i; j < n; j++) {
      const temp = matrix[i][j];
      matrix[i][j] = matrix[j][i];
      matrix[j][i] = temp;
    }
  }

  // 翻转每一行
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < n / 2; j++) {
      const temp = matrix[i][j];
      matrix[i][j] = matrix[i][n - j - 1];
      matrix[i][n - j - 1] = temp;
    }
  }

  return matrix;
}

// 测试用例
const matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
];

console.log(rotate(matrix));

输出结果:

[
  [7, 4, 1],
  [8, 5, 2],
  [9, 6, 3]
]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值