当前位置: 首页 > 知识库问答 >
问题:

javascript - 如何快速求一个排列在所有排列中的位置(按字典序排列)?

荣俊
2024-02-25

如何快速求一个排列在所有排列中的位置(按字典序排列)?

问题出自codewars Alphabetic Anagrams

我想的笨办法是

  1. 先排序得到最小的排列
  2. 和目标排列进行比较,如果相同,结束;否则调用nextPermutation计算出下一个排列
  3. 重复步骤2,3

代码实现

function listPosition(word) {  //Return the anagram list position of the word  let wd = word.split('').sort();    /*    wd: Array, represent the current permuation.    return: Array, represent the next permutation.         https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order  */  function nextPermutation(a) {    let n = a.length;    // 1. find max k, a[k] < a[k+1]    let k = -1;    for(let i = 0; i < n - 1; ++i) {      if(a[i] < a[i+1]) k = i;    }    /*      if k is not exist, state the current permutaion is the max one, don't have next permuation.    */    if(k === -1) return -1;    // 2. find max l, l > k, a[k] < a[l]    let l = -1;    for(let i = k + 1; i < n; ++i) {         if(a[i] > a[k]) l = i;    }    // 3. swap a[k] a[l]    let t = a[k];    a[k] = a[l];    a[l] = t;    // 4. reverse a[k+1...]    for(let i = k + 1, j = n-1; i < j; ++i, --j) {      let t = a[i];      a[i] = a[j];      a[j] = t;    }    return a;  }  let i;  for(i = 1; wd !== -1 && wd.join('') !== word; ++i) {    wd = nextPermutation(wd);  }  return i;}

但是超时了。

我看解答区的一个答案是这样写的,但是没看懂什么意思。

function listPosition(word) {    var indexer = {}; // D:3 B:1 A:0 C:2    var counts = []; // 2 1 1 1    var lettersCount = 0;    word.split("").sort().forEach(function(x){        if ( indexer[x] == undefined ) {            indexer[x] = lettersCount;            counts[lettersCount] = 0;            lettersCount ++;        }    });    var term = 1;    var sum = term;    word.split("").reverse().forEach(function(x, i){        var step = i + 1, idx = indexer[x];        counts[idx] ++;        term /= counts[idx];        for (var j = 0; j < idx; ++j)             if (counts[j] != 0)                 sum += term * counts[j];        term *= step;    });    return sum;}

共有1个答案

桂杰
2024-02-25

这段代码是用JavaScript编写的,用于快速求一个排列在所有排列中的位置(按字典序排列)。

代码的思路如下:

  1. 创建一个indexer对象和一个counts数组。indexer对象用于存储每个字母在排序后的字符串中的位置,counts数组用于存储每个字母的出现次数。
  2. 遍历输入的字符串,对每个字母进行排序,并更新indexercounts数组。
  3. 初始化变量term为1,sumterm
  4. 遍历排序后的字符串的逆序,更新counts数组和termsum的值。
  5. 返回sum作为结果。

具体实现中,使用了动态规划的思想,通过计算每个字母在排列中的位置和出现次数,逐步推导出最终的位置。其中,term表示当前位置相对于最前面非零出现次数的位置的倍数,sum表示从最前面非零出现次数到当前位置的所有排列的个数之和。

需要注意的是,由于使用了动态规划的思想,这段代码的时间复杂度为O(n),其中n是输入字符串的长度。

 类似资料:
  • 问题内容: 我有一本字典,其中包含以下数据: 我想按double值对字典排序。我做了一些研究,但所有示例均不支持当前版本的Swift 我试过在Swift中按值使用SortDictionary中的这段代码: 但这是行不通的。如何按字典值对字典排序? 问题答案: 目前尚不清楚您的期望是什么。确实没有排序字典这样的东西。您的代码基本上是正确的,但括号位置错误。我尝试了这个: 结果: 如果您认为这是错误的

  • 我在寻找字典上最小的字符串的排列数。 例如,< code>bbaa现在,字典上最小的字符串是< code>aabb,因此,排列是, < code>(1,2,3,4),(2,1,3,4),(1,2,4,3),(2,1,4,3)也就是4。 我对它的想法(在python中)是找到最小的字符串(基本上将其排序为字符串),然后创建一个计数器来存储每个字符的计数。 因为,我们不需要一个在字典上变得更大的字符串

  • 最新的博客地址:我的最新博客 定义 快速排序(英语:Quicksort),又称分区交换排序(partition-exchange sort),简称快排,一种排序算法,最早由东尼·霍尔提出。在平均状况下,排序 n 个项目要 O(nlogn) 次比较。在最坏状况下则需要 O(n^2) 次比较,但这种状况并不常见。事实上,快速排序 (nlogn) 通常明显比其他算法更快,因为它的内部循环(inner l

  • 问题内容: 如何在Python中生成一个列表的所有排列,独立于该列表中元素的类型? 例如: 问题答案: 从Python 2.6(如果你使用的是Python 3)开始,你可以使用标准库工具:itertools.permutations。 如果你出于某种原因使用旧版Python(),或者只是想知道它的工作原理,那么这是一种不错的方法,取自 http://code.activestate.com/rec

  • 注意:我不想使用任何库。试图解决https://icpc.kattis.com/problems/stacking 在以下条件下,合并排序数组所需的最小操作数是多少: 拆分:可以将单个堆栈拆分为两个堆栈,方法是将堆栈的任何顶部提起并放在一边,形成一个新堆栈。 连接:两个堆栈可以通过将一个放在另一个上面来连接。仅当顶部堆叠的底板不大于底部堆叠的顶板时,才允许这样做,也就是说,必须正确订购连接的堆叠。