算法 计数器_频率计数器是什么以及它们如何帮助您更好地求解算法

算法 计数器

Frequency Counters — how they can help decrease time and space complexity in algorithms

频率计数器-如何帮助减少算法中的时间和空间复杂度

In the middle of interviews and practicing never-ending algorithms, I’ve started to implement more than one solution to every problem. Mainly algorithms that require comparing two sets of arrays or objects to test similarities and differences.

在面试和实践永无止境的算法的过程中,我已经开始为每个问题实施一个以上的解决方案。 主要是需要比较两组数组或对象以测试相似性和差异性的算法。

Often, my direct solution involved nested loops to get to the answer. However, looking back at my solutions from a time and space complexity perspective (the Big O), these solutions were subpar. Yes, my solution outputs the correct result, but the larger the input the slower my algorithm becomes.

通常,我的直接解决方案涉及嵌套循环以获取答案。 但是,从时间和空间复杂性的角度( Big O )来看我的解决方案,这些解决方案是不理想的 。 是的,我的解决方案输出正确的结果,但是输入越大,算法变得越慢。

Let’s look at a couple of examples to test and see why using something other than nested loops can not only still derive the correct output, it takes exponentially faster time to compute.

让我们看几个示例进行测试,看看为什么使用嵌套循环以外的方法不仅仍然可以得出正确的输出,而且计算所需的时间也要成倍增加。

算法1 (Algorithm 1)

Write a function which accepts two arrays. The function should return true if every value in the array has it’s corresponding value squared in the second array. The frequency of values must be the same.

编写一个接受两个数组的函数。 如果数组中的每个值在第二个数组中都有对应的值平方,则该函数应返回true。 值的频率必须相同。

Outputs should look like: same([1,2,3], [4,1,9]) // true
same([1,2,3], [1,9]) // false
same([1,2,3], [4,4,1]) // false (must be same frequency)

My initial ‘naive’ approach:

我最初的“天真”方法:

function same(arr1, arr2) {// knockout future logic if the arrays do not have the same lengthif (arr1.length !== arr2.length) {
return false }// loop through one arrayfor (let i = 0; i < arr1.length; i++) {// loop through second array using indexOf to see if index ** 2 existslet correctIndex = arr2.indexOf(arr[i] ** 2);//if the index doesn’t exist in the second array, return false and stopif (correctIndex === -1) {
return false }// if the index does exist, clean the array (splice) until the array length is 0arr2.splice(correctIndex, 1) {
return true } }

This function will output true or false correctly depending on the input it is given. However, let’s get how many loops we are requiring to get to our final answer:

根据给定的输入,此函数将正确输出true或false。 但是,让我们得出需要多少个循环才能得出最终答案:

  1. Loop through first array

    遍历第一个数组
  2. 2. Nested loop through second array (indexOf is a nested loop)

    2.通过第二个数组的嵌套循环( indexOf是一个嵌套循环)

bringing our Big O in this case to . Not so efficient in terms of time and space complexity.

在这种情况下将我们的Big O带到 。 就时间和空间复杂性而言,效率不高。

Now, let’s look at the same problem but solve it with a different approach to avoid nested looping — with frequency counters:

现在,让我们看一下相同的问题,但是使用不同的方法来解决它,以避免嵌套循环—使用频率计数器:

function same(arr1, arr2) {// like before, don’t continue further logic is array lengths do not match
if (arr1.length !== arr2.length) {
return false }// to count the frequency of each character in each array, declare two objects
let frequencyCounter1 = { };
let frequencyCounter2 = { };// loop through array1 and set key and values for each characterfor (let value of arr1) {
frequencyCounter1[value] = (frequencyCounter1[value] || 0) + 1 }// loop through array1 and set key and values for each characterfor (let value of arr2) {
frequencyCounter2[value] = (frequencyCounter2[value] || 0) + 1 }//sets the counts into two objects, now compare
// search for a squared key in second array for each key in array 1
for (let key in frequencyCounter1) {
if (!(key ** 2 in frequencyCounter2)) {
return false }// search for the values of the matching keys to make sure they are the same, if not stopif(frequencyCounter2[key**2] !== frequencyCounter1[key]) {
return false } // if all goes through, the keys on the second array and squared values of the first array and the values are the same, go ahead and return trueelse {
return true } }

At first, this solution looks much longer and if you’re looking at it for the first time it may even take a bit of time to correctly understand what’s going on. However, putting the logic to the side and actually counting the loops in this solution to achieve a big idea picture of time/space complexity you’ll see that there are only 2 loops. It doesn’t matter how long the arrays are; each array will only be looped through once. Then there is a search method within an object, which takes very little time (one of the quickest processes to receive information from objects). This concludes the solution to have a Big O of (2n) which we can round to just (n).

刚开始时,此解决方案的外观要长得多,如果您是第一次使用它,甚至可能需要花费一些时间才能正确了解正在发生的事情。 但是,将逻辑放到一边,并在此解决方案中实际计数循环,以大致了解时间/空间复杂度,您会看到只有2个循环。 数组有多长都没有关系; 每个数组只会循环一次。 然后,在对象内有一种搜索方法,该方法只需很少的时间(从对象接收信息的最快过程之一)。 至此,我们得出了一个大O (2n)的解决方案,我们可以将其舍入为(n)

As you can see a little more clearly now (hopefully!) that our second approach is significantly faster than our initial approach. Let’s take a look at another example to further clarify this conclusion.

如您现在所看到的(希望如此),我们的第二种方法比初始方法要快得多。 让我们看另一个示例,以进一步阐明这一结论。

算法2 (Algorithm 2)

Given two strings, write a function to determine if the second string is an anagram of the first. An anagram is a word, phrase, or name formed by rearranging the letters of another, such as cinema, formed from iceman.

给定两个字符串,编写一个函数以确定第二个字符串是否是第一个字符串的字谜。 字谜是重新排列由冰人形成的另一个字母(例如电影)的字母而形成的单词,词组或名称。

Initial approach:

初始方法:

function isValidAnagram(str1, str2){// knockout further logic if strings do not match in lengthif(str1.length !== str2.length) {
return false }// loop through one arrayfor (let i = 0; i < str1.length; i++) {//check if each instance of i matches an index of second stringlet sameChar = str2.indexOf(str1[i])//if there is no match, stop — return falseif (sameChar === -1) {
return false } }// all are matches, go ahead and return true return true } }

‘Short and Sweet?’ Is something I hope you’re not thinking if you’ve read this far. Although this will output true if both strings consist of the same character frequencies and false if not; the big O of this solution is due to the nested looping over the second string using the built-in method indexOf.

“简短而甜蜜?” 我希望您不要在意是否已读完本文。 尽管如果两个字符串包含相同的字符频率将输出true,否则输出false。 由于使用内置方法indexOf在第二个字符串上嵌套循环,因此该解决方案的大O

Let’s look at an approach to this problem with a frequency counter:

让我们看一下使用频率计数器解决此问题的方法:

function isValidAnagram(str1, str2) {// do not go further if the lengths of both strings are not equalif(str1.length !== str2.length) {
return false }// declare an object that will set up the characters as keys and its frequencies as valueslet lookup = { };// loop through one string and count the frequencies of each characterfor (let i = 0; i < str1.length; i++) {
let letter = str1[ i ]// add these values to the ‘lookup’ objectlookup[ letter ] ? lookup[letter] + 1 : lookup[letter] = 1 }// now loop through second string and check to see if the ‘lookup’ object consists of the same keysfor (let i = 0; i < str2.length; i++) {
let letter = str2[ i ]// if there’s a key that doesn’t match, stop — return falseif ( ! (lookup[letter])) {
return false }// if the key matches decrease its frequency value by 1else {
lookup[letter] = lookup[letter] — 1 } }// finish and return true when all frequency values decrease to 0return true } }

This solution loops through both strings once depending on how big the string length (n) is. It notes all its findings in an object, to search through later — this as we stated previously, doesn’t take much time bringing the Big O of this solution to (n).

此解决方案根据字符串长度(n)的长度在两个字符串之间循环一次。 它在一个对象中记录了所有发现,以便以后进行搜索-正如我们之前所说,将这个解决方案的Big O引入(n)并不需要花费很多时间。

I hope that taking a closer look at both of these algorithm solutions justify that using something like a frequency counter to note similarities or differences between two data structures takes up much less time and space (when speaking of big O) and thus much more efficient.

我希望仔细研究这两种算法,可以证明使用频率计数器之类的东西来记录两个数据结构之间的相似性或差异性会占用更少的时间和空间(谈到大O时),从而提高效率。

Good luck to all those practicing algorithms and hope that this is of benefit!

祝所有练习算法的人好运,并希望这对您有所帮助!

翻译自: https://medium.com/@samanbatool08/frequency-counters-what-are-they-and-how-they-can-help-you-solve-algorithms-with-greater-56b71d76fcdd

算法 计数器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值