简体   繁体   English

如何检查两个字符串在O(n)时间中是否彼此置换? (java)

[英]How can I check if two strings are permutations of each other in O(n) time? (java)

I wrote this class that can check if two given strings are permutations of each other. 我编写了此类,可以检查两个给定的字符串是否彼此置换。 However, it is my understanding that this runs at O(n^2) time because the string.indexOf() runs at O(n) time. 但是,据我了解,此操作在O(n ^ 2)时间运行,因为string.indexOf()在O(n)时间运行。

How can this program be made more efficient? 如何使该程序更有效率?

import java.util.*;

public class IsPermutation{
   public void IsPermutation(){
      System.out.println("Checks if two strings are permutations of each other.");
      System.out.println("Call the check() method");
   }

   public boolean check(){
      Scanner console = new Scanner(System.in);
      System.out.print("Insert first string: ");
      String first = console.nextLine();
      System.out.print("Insert second string: ");
      String second = console.nextLine();

      if (first.length() != second.length()){
         System.out.println("Not permutations");
         return false;
      }

      for (int i = 0; i < first.length(); i++){
         if (second.indexOf(first.charAt(i)) == -1){
            System.out.println("Not permutations");
            return false;
         } 
      }
      System.out.println("permutations");
      return true;
   }
}

First, it can be done in O(nlogn) by sorting the two strings (after converting them to char[] ), and then simple equality test will tell you if the original strings are permutations or not. 首先,可以通过对两个字符串进行排序(在将它们转换为char[]之后O(nlogn)O(nlogn)完成,然后简单的相等性测试将告诉您原始字符串是否是置换的。

An O(n) solution average case can be achieved by creating a HashMap<Character, Integer> , where each key is a character in the string, and the value is the number of its occurances (This is called a Histogram ). 通过创建HashMap<Character, Integer>可以实现O(n)解决方案的平均情况,其中每个键是字符串中的一个字符,而值是其出现的次数(这称为直方图 )。 After you have it, again a simple equality check of the two maps will tell you if the original strings are permutations. 完成后,再次对这两个映射进行简单的相等性检查将告诉您原始字符串是否为置换。

One way to archive O(n) is to count the frequency of every character. 存档O(n)的一种方法是计算每个字符的频率。

I would use a HashMap with the characters as keys and the frequencys as values. 我将使用HashMap,将字符作为键,将频率作为值。

//create a HashMap containing the frequencys of every character of the String  (runtime O(n) )
public HashMap<Character, Integer> getFrequencys(String s){
    HashMap<Character, Integer> map = new HashMap<>();

    for(int i=0; i<s.length(); i++){
        //get character at position i
        char c = s.charAt(i);

        //get old frequency (edited: if the character is added for the 
        //first time, the old frequency is 0)
        int frequency;
        if(map.containsKey(c)){
            frequency = map.get(c);
        }else{
            frequency = 0;
        }
        //increment frequency by 1
        map.put(c, frequency+1 );
    }

    return map;
}

now you can create a HashMap for both Strings and compare if the frequency of every character is the same 现在您可以为两个字符串创建一个HashMap并比较每个字符的频率是否相同

//runtime O(3*n) = O(n)
public boolean compare(String s1, String s2){
    if(s1.length() != s2.length()){
        return false;
    }

    //runtime O(n)
    HashMap<Character, Integer> map1 = getFrequencys(s1);
    HashMap<Character, Integer> map2 = getFrequencys(s2);

    //Iterate over every character in map1 (every character contained in s1)  (runtime O(n) )
    for(Character c : map1.keySet()){
        //if the characters frequencys are different, the strings arent permutations
        if( map2.get(c) != map1.get(c)){
            return false;
        }
    }

    //since every character in s1 has the same frequency in s2,
    //and the number of characters is equal => s2 must be a permutation of s1

    return true;
}

edit: there was a nullpointer error in the (untested) code 编辑:(未经测试)代码中存在nullpointer指针错误

Sorting Solution: 排序解决方案:

public void IsPermutation(String str1, String str2) {
  char[] sortedCharArray1 = Arrays.sort(str1.toCharArray());
  char[] sortedCharArray2 = Arrays.sort(str2.toCharArray());

  return Arrays.equals(sortedCharArray1, sortedCharArray2);
}

Time Complexity: O(n log n) Space Complexity: O(n) 时间复杂度:O(n log n)空间复杂度:O(n)

Frequency count solution: 频率计数解决方案:

//Assuming that characters are only ASCII. The solutions can easily be modified for all characters

public void IsPermutation(String str1, String str2) {
    if (str1.length() != str2.length())
        return false;

    int freqCountStr1[] = new int[256];
    int freqCountStr2[] = new int[256];

    for (int i = 0; i < str1.length(); ++i) {
        int c1 = str1.charAt(i);
        int c2 = str2.charAt(i);
        ++freqCountStr1[c1];
        ++freqCountStr2[c2];
    }

    for (int i = 0; i < str1.length(); ++i) {
        if (freqCountStr1[i] != freqCountStr2[i]) {
            return false;
        }
    }

    return true;
  }
}

Time Complexity: O(n) Space Complexity: O(256) 时间复杂度:O(n)空间复杂度:O(256)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 检查两个字符串是否是彼此的排列 - Checking if two strings are permutations of each other 检查两个 arrays 是否是彼此递归的排列 - check if two arrays are permutations of each other recursive 如何测试两个字符串是否相互旋转? - How can I test whether two strings are rotations of each other? 如何修改此代码以使时间复杂度为o(log n)或o(n)而不是o(n ^ 2) - how can i amend this code to have a time complexity of o(log n) or o(n) instead of o(n^2) 如何在Java中找到两个彼此相似的字符串? - how can I find two string are similar to each other in java? 检查两个字符串是否彼此置换? - check if two strings are permutation of each other? 有没有办法在少于 O(n) 的时间内连接 Java 字符串? - Is there a way to concatenate Java strings in less than O(n) time? 如何检查两个字符串是否是字谜? - How can I check if two strings are anagrams? 在java中的neo4j嵌入式数据库中,我应该如何检查两个节点是否相互关联? - How should I check if two nodes have relationship with each other,in neo4j embedded database in java? 如何在时间 O(n) 和空间 O(1) 的情况下找到最大差异为 0 和 1 的最长子数组 - how can i find the longest subarray with a max difference of 0 and 1 with time O(n) and space O(1)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM