前端算法 贪心

80 阅读1分钟

1.剪绳子
给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m] 。请问 k[0]k[1] ...*k[m] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

function cuttingRope(n) {
    if (n <= 3) return n - 1
    var times = Math.floor(n / 3) // 有几个3
    var over = n % 3 // 次数
    if(over == 0) return Math.pow(3, times)
    if(over == 1) return Math.pow(3, times - 1) * 4
    return Math.pow(3, times) * 2
};

2.跳跃游戏
给定一个非负整数数组,你最初位于数组的第一个位置。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个位置。

function canJump(nums) {
    let max = 0;
    for (let i = 0; i < nums.length; i++) {
        if (i > max) {
            return false;
        }
        max = Math.max(max, i + nums[i]);
        if (max >= nums.length - 1) {
            return true;
        }
    }
    return false;
};

3.加油站
在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1

function canCompleteCircuit(gas, cost) {
  let total = 0; // 总的剩余油料
  let curr = 0;  // 当前站点的剩余油料
  let start = 0; // 起始点
  for(let i = 0; i < gas.length; i++) {
    curr += gas[i] - cost[i];
    if (curr < 0) {
      start = i + 1;
      curr = 0;
    }
    total += gas[i] - cost[i]
  }
  return total >= 0 ? start: -1;
};