力扣竞赛247期(下)| 8月更文挑战

212 阅读2分钟

1915. 最美子字符串的数目

截屏2021-08-01 下午5.55.55.png

思路分析

这道题有浓烈的“滑动窗口”的既视感,题目中出现了两次“线索”,

  1. 字母的组成只有十种——很明显,这是为了降低数据的复杂度,让你从26行的数组变成了10行的数组。什么?为什么默认是二维数组,因为一位数组没必要降低数据的复杂度.
  2. 每次出现分别计数,看起来这是在帮我们节省了一个去重的步骤,但其实这甚至帮我减少了计数时的“求甚解”。 如果说看这题第一眼你觉得是滑动窗口,但这个时候你已经可以想到前缀和了。

很明显这是一道二维数组的前缀和,每列是数组从0到j都有多少个第i个字母的个数(发现这句话很难用语言描述),show me code


int arr[m][n];

for(int i = 0; i < nums.size(); i++){
    
    for(int j = 0; j < 10; j++){
        arr[i][j] = arr[i - 1][j]
    }
    int idx = (nums[i] - 'a');
    arr[i][idx] ++;
    
}

那么计算子字符串奇数的个数便变得显而易见了。

1916. 统计为蚁群构筑房间的不同顺序

截屏2021-08-02 下午7.56.37.png

截屏2021-08-02 下午7.57.03.png

思路分析

写在前面:这道题最后变成了数学题,所以本文不会讲后续的数学推导(老子不会)

如果说对时间复杂度完全没有要求的话,我们可以使用dfs去做这道题,这道题也是很简单的dfs。本题中对顺序的要求,也可以理解为通过判断前置节点是否已读的方式来实现。

但是如果不希望使用n!的复杂度的话,就只能使用动态规划解决。

假设根结点为u,假设其具有子节点v1,v2,,,viv_1,v_2,,,v_ivi节点有num[vi]种可能排列v_i节点有num[v_i]种可能排列,那么对于nums[u],我们需要计算u下面节点总数量的全排列!每个子树全排列\frac{u下面节点总数量的全排列!}{\prod每个子树全排列} ,这会算出排除子树内部的排序顺序后,子树之间的排序数量,最后用这个数量乘以所有的nums[vi]nums[v_i],就得到了答案