算法-贪心算法&回溯算法

162 阅读1分钟

贪心算法

  • 贪心算法是算法设计的一种思想;
  • 期盼通过每个阶段的局部最优选择,从而达到全局的最优。结果并不一定是最优;
练习题

455. 分发饼干

// 局部最优,既能满足孩子,又能消耗最少。将较小的饼干分配给胃口较小的孩子。
  var findContentChildren = function (g, s) {
    g.sort((a, b) => a - b);
    s.sort((a, b) => a - b);
    let index = 0;
    s.forEach((item) => {
      if (item >= g[index]) {
        index++;
      }
    });
    return index;
  };

122. 买卖股票的最佳时机 II

// 见好就收,见差就不动,不考虑未来的收益;
 var maxProfit = function (prices) {
   let res = 0;
   for (let i = 0; i < prices.length; i++) {
     if (prices[i] > prices[i - 1]) {
       res += prices[i] - prices[i - 1];
     }
   }
   return res;
 };

回溯算法

  • 回溯算法是算法设计的一种方法;
  • 回溯算法是一种渐进式寻找并构建问题解决方式的策略;
  • 回溯算法会先从一个动作开始解决问题,如果不行,就回溯并选择另一个动作直到将问题解决;
练习题

46. 全排列

//需要用递归模拟所有情况;遇到包含重复元素的情况就回溯;收集所有到达递归终点的情况,并返回。
var permute = function (nums) {
  const res = [];
  const rec = (path) => {
    if (path.length === nums.length) {
      res.push(path);
      return;
    }
    nums.forEach((item) => {
      if (!path.includes(item)) {
        rec([...path, item]);
      }
    });
  };
  rec([]);
  return res;
};

78. 子集

// 用递归模拟出所有情况,保证接的子树都是后面数字,收集所有到达递归终点的情况,并返回。
 var subsets = function (nums) {
   let res = [];
   const backtrack = (path, len, start) => {
     if (path.length === len) {
       res.push(path);
       return;
     }
     for (let i = start; i < nums.length; i++) {
       backtrack(path.concat(nums[i]), len, i + 1);
     }
   };
   for (let i = 0; i <= nums.length; i++) {
     backtrack([], i, 0);
   }
   return res;
 };