代码随想录第27天|39. 组合总和、40. 组合总和 II、131. 分割回文串

52 阅读1分钟

39. 组合总和

1. first idea

  1. Params: tmp_sum of tmp_list, tmp_list.
  2. Return: we can conduct pruning by judge the current tmp_sum + nums[idx] <= traget, if it not satisfying the condition, we do not recursion. We return directly.
  3. our for cycle in the current level need to be start from the previous element of the tmp_list.
class Solution:
    def __init__(self):
        self.res_list = []

    def traversal(self, candidates, tmp_list, tmp_sum, target, st_idx):
        if tmp_sum == target:
            self.res_list.append(tmp_list)
        else:
            for idx in range(st_idx, len(candidates)):
                if tmp_sum + candidates[idx] <= target:
                    self.traversal(candidates, tmp_list + [candidates[idx]], tmp_sum + candidates[idx], target, idx)

    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        self.traversal(candidates, [], 0, target, 0)
        return self.res_list

2. learning time

26min.

40. 组合总和 II

1. first idea

  1. use start_idx to record which element in the candidates we have used before
  2. use for i in range(start_idx, len(candidates)) to check each of the elements to avoid repetition.
    1. (Not enough! Because of the different elements may equal in value.)
    2. if we sort the candidates at first. When we meet the continue elements, we just only choose the first for recursion in a level.
  3. stop condition: if tmp_list == target. add the tmp_list into res_list for recording.
  4. params: candidates, start_idx, tmp_sum, target, tmp_list

2. read doc

The key point is wheter we want to avoid the repetition in a level or in a branch.

if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false) {
        continue;
    }

Write the code above after sort candidates is equal to

if candidates[i] in level_record: 
    continue

A more simple code is as follows:

// 要对同一树层使用过的元素进行跳过
if (i > startIndex && candidates[i] == candidates[i - 1]) {
    continue;
}

If the candidates[i] is not the start node of this level, and equal to start node value, just skip.

3. learning time

53min.

131. 分割回文串

1. first idea

We need to return the splitting scheme, not the sub-string. My idea is as this. image.png So we can use for cycle along with the length of the first sub-string.

  1. stop condition: All characters in string have been read, and current sub-string is Palindromic string。
  2. params: tmp_list, tmp_substr_list.
  3. for i in range(1, len(tmp_substr_list) + 1) recursion with tmp_substr_list[:i].
class Solution:
    def __init__(self):
        self.res_list = []
    
    def judge_pal(self, sub_str_list):
        for i in range(0, len(sub_str_list) // 2):
            if sub_str_list[i] != sub_str_list[-(1 + i)]:
                return False
        return True
    
    def track_back(self, tmp_substr_list, tmp_list):
        if len(tmp_substr_list) == 0:
            self.res_list.append(tmp_list)
        else:
            for i in range(1, len(tmp_substr_list) + 1):
                if self.judge_pal(tmp_substr_list[:i]):
                    self.track_back(tmp_substr_list[i:], tmp_list + ["".join(tmp_substr_list[:i])])

    def partition(self, s: str) -> List[List[str]]:
        self.track_back(list(s), [])
        return self.res_list

2. learning time

40min.