8.6 KiB
8.6 KiB
title | localeTitle |
---|---|
No Repeats Please | 请不要重复 |
如果卡住,请记得使用**Read-Search-Ask
** 。尝试配对程序并编写自己的代码
问题说明:
此任务要求我们返回没有重复连续字母的提供字符串的总排列数。假设所提供的字符串中的所有字符都是唯一的。例如, aab
应该返回2,因为它总共有6个排列( aab
, aab
, aba
, aba
, baa
, baa
),但只有2个( aba
和aba
)没有相同的字母(在这种情况下为a
)重复。
为此,我们必须查看字符串的每个可能的排列。有几种方法可以做到这一点。一个常见的面试问题是构建一个收集字符串所有排列的函数。互联网上有几个关于如何做到这一点的教程。
用作解决方案的潜在方法
递归方法
即使在观看教程之后,这项任务也令人望而生畏。要编写递归解决方案,您需要发送函数的每个新用法三个输入:
- 正在构建的新字符串(或字符数组)。
- 新字符串中的一个位置将在下一个填充。
- 还没有使用原始字符串中的字符(更具体地说是位置)的想法。
伪代码看起来像这样:
var str = ???;
permAlone(current position in original string, characters used already in original string, created string) {
if (current string is finished) {
print current string;
} else {
for (var i = 0; i < str.length; i++) {
if (str[i] has not been used) {
put str[i] into the current position of new string;
mark str[i] as used;
permAlone(current position in original string, characters used already in original string, created string);
remove str[i] as used because another branch in the tree for i + 1 will likely use it;
}
}
}
}
permAlone(0, nothing used yet, empty new string (or array the same size as str));
考虑这个问题的另一种方法是从一个空的空间开始。介绍该空间的第一个字母。此空间现在将包含第一个子排列。这是一个说明这个想法的图表:
非递归方法
// An approach to introduce a new character to a permutation
var ch = '?';
var source = ['?', '?', '?']; // Current sub-permutation
var temp, dest = [];
for (var i = 0; i <= source.length; ++i) {
temp = source.slice(0); // Copy the array
temp.splice(i, 0, ch); // Insert the new character
dest.push(temp); // Store the new sub-permutation
}
然后,通过将上述内容包括在采用源阵列并返回目标阵列的函数中,可以非递归地完成每个置换。对于输入字符串的每个字母,传递该字符,以及从上一次调用函数返回的数组。
可视化这种方法的方法是考虑以字符串的第一个字符开头的树:
相关链接
- 排列
- Heap的算法
- JS Regex资源
- JS String对象
提示:1
- 最简单的方法是使用Heap算法递归获取所有排列的列表。
现在尝试解决问题
提示:2
- 获得列表后,只需创建一个正则表达式来捕获重复的字符。
现在尝试解决问题
提示:3
- 您将希望将排列作为连接字符串的数组而不是分隔的字符。
现在尝试解决问题
扰流警报!
提前解决!
基本代码解决方案
function permAlone(str) {
// Create a regex to match repeated consecutive characters.
var regex = /(.)\1+/g;
// Split the string into an array of characters.
var arr = str.split('');
var permutations = <a href='https://forum.freecodecamp.com/images/emoji/emoji_one/rocket.png?v=3 ":rocket:"' target='_blank' rel='nofollow'>];
var tmp;
// Return 0 if str contains same character.
if (str.match(regex) !== null && str.match(regex)[0] === str) return 0;
// Function to swap variables' content.
function swap(index1, index2) {
tmp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = tmp;
}
// Generate arrays of permutations using the algorithm.
function generate(int) {
if (int === 1) {
// Make sure to join the characters as we create the permutation arrays
permutations.push(arr.join(''));
} else {
for (var i = 0; i != int; ++i) {
generate(int - 1);
swap(int % 2 ? 0 : i, int - 1);
}
}
}
generate(arr.length);
// Filter the array of repeated permutations.
var filtered = permutations.filter(function(string) {
return !string.match(regex);
});
// Return how many have no repetitions.
return filtered.length;
}
// Test here.
permAlone('aab');
代码说明:
- 正则表达式包含匹配重复连续字符的正则表达式。
- 字符串str被分成一个字符数组arr 。
- 如果str包含相同的字符,则返回0。
- 函数
swap()
用于交换两个变量内容的内容。 - 下一个代码块使用堆的算法来产生在排列的排列的阵列。
- 过滤的变量过滤排列以仅包括非重复的排列。
filtered.length
返回没有重复连续字母的提供字符串的总排列数。
相关链接
- JS String Prototype Split
- JS String Prototype Match
- JS阵列原型推送
- JS Array Prototype Join
- JS for Loops解释
- array.length
- JS数组原型过滤器
捐款说明:
- 请勿添加与任何现有解决方案类似的解决方案。如果您认为它**相似但更好** ,那么尝试合并(或替换)现有的类似解决方案。
- 添加解决方案的说明。
- 将解决方案分为以下类别之一 - 基本 , 中级和高级 。
- 如果您添加了任何**相关的主要内容,**请仅添加您的用户名。 ( 不要 删除任何现有的用户名 )