回溯算法(试探算法)

本文目录

1 基本概念

2 分割回文串

3 相关文章


 

1 基本概念

回溯算法试探算法)是一种按指定策略遍历所有可能路径的方法,在遍历的过程中,找出所有满足条件的解。每走一步,判断当前情况是否满足条件,若满足条件,则在该路径上继续试探,若不满足条件,则回溯(回退)至上一步,然后换一条路径继续试探。

 

2 分割回文串

例题:给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。返回 s 所有可能的分割方案。

出自:中文版 LeetCode 第 131 题 - 分割回文串 问题

思路:

先寻找第一个满足条件的子字符串,记录结束位置为 endIndex1;再从 endIndex1 + 1 位置开始,寻找第二个满足条件的子字符串,记录结束位置为 endIndex2;以此类推,当最后一个满足条件的子字符串结束位置正好在原字符串 s 结尾处,则表示正好将原字符串 s 分割为多个回文子串,即该分割方案是满足条件的一个解。

class Solution {

  private boolean[] indexFlag;
  private List> resultList;

  public List> partition(String s) {
    indexFlag = new boolean[s.length()];  // 记录分割点
    resultList = new ArrayList<>();
    findSubPalStr(s, 0);  // 从0下标点开始遍历
    return resultList;
  }

  /**
   * 回溯算法:从指定位置开始寻找下一个回文子串
   */
  private void findSubPalStr(String s, int startIndex) {
    for (int endIndex = startIndex; endIndex < s.length(); endIndex++) {
      if (isPalindrome(s, startIndex, endIndex)) {  // 判断当前子串是否为回文(当前步骤是否满足条件)
        indexFlag[endIndex] = true;  // 记录分割点
        if (!isSolution(s, endIndex)) { // 判断是否为题解
          findSubPalStr(s, endIndex + 1);  // 非题解:进行下一步尝试
        }
        indexFlag[endIndex] = false;  // 抹除记录:回溯至上一步状态
      }
    }
  }

  /**
   * 当前步骤判断:是否为回文串
   */
  private boolean isPalindrome(String s, int leftIndex, int rightIndex) {
    while (leftIndex <= rightIndex && s.charAt(leftIndex) == s.charAt(rightIndex)) {
      leftIndex++;
      rightIndex--;
    }
    return leftIndex >= rightIndex;
  }

  /**
   * 整体方案判断:是否将原字符串 s 正好分割为多个回文子串,即 当前方案是否为题解。
   */
  private boolean isSolution(String s, int currentIndex) {
    // 判断条件:当前位置正好在原字符串 s 结尾处,表示正好将 原字符串 s 分割为多个回文子串。
    if (currentIndex == s.length() - 1) {
      List resultItem = new ArrayList<>();
      // 遍历分割点 并 构造结果项
      for (int start = 0, end = 0; end < indexFlag.length; end++) {
        if (indexFlag[end]) {
          resultItem.add(s.substring(start, end + 1));
          start = end + 1;
        }
      }
      resultList.add(resultItem);
      return true;
    }
    return false;
  }
}

 

扩展内容:

由于该题需要找到所有满足条件的方案,因此,使用回溯算法进行求解。

若该题只需要判断是否存在满足条件的方案,则可以使用动态规划进行求解,其思路可参考《动态规划:单词拆分》。

 

3 相关文章

《全排列(Java)》

《位运算:减法与补码》

《异或(^)的性质与应用》

《图解:常用排序算法(冒泡、选择、插入、希尔、快速、归并、堆)》

《动态规划:鸡蛋掉落》

《动态规划:单词拆分》

《状态机:只出现一次的数字II》

《最小堆:TopK问题》

《链表:快慢指针》

 

你可能感兴趣的:(Algorithm)