LeetCode刷题 Day27

82 阅读2分钟

LeetCode刷题 Day27

39. Combination Sum

Given an array of distinct integers candidates and a target integer target, return a list of all unique combinations of candidates where the chosen numbers sum to target .  You may return the combinations in any order.

The same number may be chosen from candidates an unlimited number of times. Two combinations are unique if the 

frequency

 of at least one of the chosen numbers is different.

The test cases are generated such that the number of unique combinations that sum up to target is less than 150 combinations for the given input.

 

Example 1:

Input: candidates = [2,3,6,7], target = 7
Output: [[2,2,3],[7]]
Explanation:
2 and 3 are candidates, and 2 + 2 + 3 = 7. Note that 2 can be used multiple times.
7 is a candidate, and 7 = 7.
These are the only two combinations.

Example 2:

Input: candidates = [2,3,5], target = 8
Output: [[2,2,2,2],[2,3,3],[3,5]]

Example 3:

Input: candidates = [2], target = 1
Output: []

思路: 这个题的重点依然是搞清楚树中横向和纵向的技巧。这道题纵向是可以重复选择的:

  • 以index = 0为起点,选了index 0的element之后,进入下一层依然可以选择index 为0 的数字。
  • 但是要注意,当选完某个index的element之后,不能再反向去选择index - 1, index - 2的数字了。所以要搞清楚如何定义startIndex这个参数。
  • 将startIndex 赋值为遍历的i,这样把起点固定住,纵向递归的时候就不会选到i < startIndex的数了。

代码:

var combinationSum = function(candidates, target) {
    let path = [];
    let res = [];
    let helper = function(path, sum, startIndex) {
        if (sum > target) return;
        if (sum === target) {
            res.push([...path]);
            return;
        }

        for (let i = startIndex; i < candidates.length; i++) {
            path.push(candidates[i]);
            helper(path, sum + candidates[i], i);
            path.pop();
        }
    }

    helper([], 0, 0);
    return res;
};

40. Combination Sum II

Each number in candidates may only be used once in the combination.

Note: The solution set must not contain duplicate combinations.

Example 1:

Input: candidates = [10,1,2,7,6,1,5], target = 8
Output: 
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]

Example 2:

Input: candidates = [2,5,2,1,2], target = 5
Output: 
[
[1,2,2],
[5]
]

思路:

  • 这道题的关键依然在于去重,按照题中的意思,选中了[1,2,5]就不能再选[2,1,5]。那么首先想到是做个排序,这样方便将相邻的数做一个比较,然后通过比较的结果去重。
  • 排序之后[1,1,2,5,6,7,10],可以发现 index 1和2的数是相同的这样就会有1,2,5 + 1,2,5的重复组合, 所以我们要判断一下startIndex重复element:
  if (i > level && candidates[i] === candidates[i - 1]) continue;

代码:

var combinationSum2 = function(candidates, target) {
    let res = [];
    candidates.sort((a, b) => a - b);

    let helper = function(path, sum, level) {
        if (sum > target) return;
        if (sum === target) {
            res.push([...path]);
            return;
        }

        for (let i = level; i < candidates.length; i++) {
            if (i > level && candidates[i] === candidates[i - 1]) continue;
            path.push(candidates[i]);
            helper(path, sum + candidates[i], i + 1);
            path.pop();
        }
    }

    helper([], 0, 0);

    return res;
};

131. Palindrome Partitioning

Given a string s, partition s such that every 

substring

 of the partition is a 

palindrome

Return all possible palindrome partitioning of s.

Example 1:

Input: s = "aab"
Output: [["a","a","b"],["aa","b"]]

Example 2:

Input: s = "a"
Output: [["a"]]

思路:

-这个就是一个无重复的组合问题, startIndex 作为起点, i 作为终点去得到substring。如果substring是 回文的,即可进行回溯操作。 终止条件为startIndex >= s.length - 1。

image.png 代码:

var partition = function(s) {
    let res = [];
    
    var helper = function(start, path) {
        if (start > s.length - 1) {
            res.push([...path]);
            return;
        }
        
        for (let i = start; i < s.length; i++) {
            let sub = s.substring(start, i + 1);
            if (isPalindrome(sub) && sub.length > 0) {
                path.push(sub);
                helper(i + 1, path);
                path.pop();
            }
        }
    }
    
    helper(0, []);
    
    return res;
};

var isPalindrome = function(s) {
    let l = 0;
    let r = s.length - 1;
    
    while (l < r) {
        if (s[l] !== s[r]) return false;
        l++;
        r--;
    }
    
    return true;
}