Leetcode1002. Найти общие символы между строками -Java

#java #algorithm

#java #алгоритм

Вопрос:

Вопросы были следующими: Учитывая массив строк A, состоящий только из строчных букв, верните список всех символов, которые отображаются во всех строках в списке (включая дубликаты). Например, если символ встречается 3 раза во всех строках, но не 4 раза, вам нужно включить этот символ три раза в окончательный ответ.

Вы можете вернуть ответ в любом порядке.

Пример 1:

Входные данные: [«bella», «label», «roller»] Выходные данные: [«e», «l»,»l»]

Пример 2:

Ввод: [«cool», «lock», «cook»] Вывод: [«c»,»o»]

Примечание:

1 <= A.длина <= 100

1 <= A[i].длина <= 100

A[i][j] — это строчная буква

Это мой код:

 class Solution {
    public List<String> commonChars(String[] A) {
        List<String> charArr = new ArrayList<>();

        for(int i = 1; i<A.length ; i  ){
            A[0].replaceAll("[^"   A[i]   "]", "");
        }
        for(int i=0; i<A[0].length(); i  ){
            charArr.add(Character.toString(A[0].charAt(i)));
        }
        return charArr;

    }
}
  

Результат, который я получил

входные данные: [«bella», «label», «roller»]

Вывод: [«b», «e», «l», «l»,»a»]

Ожидается: [«e», «l»,»l»]

Очевидно, что символы не были удалены, кто-нибудь может помочь мне с этой проблемой?

Комментарии:

1. A[0].replaceAll(«[^» A[i] «]», «»); вам нужно присвоить это значение строке. например, A[0] = A[0].replaceAll(«[^» A[i] «]», «»); На этом алгоритм все еще не завершен, но я думаю, что это хороший первый пункт для продвижения вперед. Итак, причина, по которой вы видите все символы bella в выходных данных, заключается в том, что первый цикл for, по сути, ничего не делает.

2. Использование replaceAll просто не может дать правильный ответ на количество дубликатов определенной буквы. Например, если ввод [aaa, a] , вы бы вернули [a, a, a] , что неверно, поскольку вторая строка содержит только одну a . Переосмыслите, что вы пытаетесь сделать.

3. То, что вы делаете, отличается от того, что вопрос хочет, чтобы вы сделали.

Ответ №1:

Не уверен насчет java, но вот строка 1 в python

 list(functools.reduce(lambda a,b: aamp;b, [Counter(c) for c in A]).elements())
  
 >>> from collections import Counter
>>> import functools

>>> A = ["bella","label","roller"]
>>> list(functools.reduce(lambda a,b: aamp;b, [Counter(c) for c in A]).elements())
['e', 'l', 'l']
>>> A =  ["cool","lock","cook"]
>>> list(functools.reduce(lambda a,b: aamp;b, [Counter(c) for c in A]).elements())
['c', 'o']
>>>
  

Ответ №2:

Я решил проблему с помощью идеи Манаара, спасибо всем за предложения и комментарии!

 **class Solution {
    public List<String> commonChars(String[] A) {
        List<String> charArr = new ArrayList<>();
        int[][] lowerCase = new int[26][A.length];
        for(int i = 0 ; i< A.length ; i  ){
            for(int j =0; j<A[i].length();j  )
            lowerCase[A[i].charAt(j)-'a'][i]   ;            
        }
        for(int i =0; i < 26 ;i  ){
            int min = lowerCase[i][0];
            for(int j = 0 ; j< A.length ; j  ){
                if(lowerCase[i][j]<min)
                    min = lowerCase[i][j];
            }
            while(min!=0){
                charArr.add(Character.toString((char)(i 'a')));
                min--;

            }
        }
        return charArr;
    }
}
  

Комментарии:

1. Это хорошее решение. Результат в Leetcode: Время выполнения: 3 мс, быстрее, чем 87,52% онлайн-заявок на Java. Очень хорошо.

Ответ №3:

Вот некоторый псевдокод для того, как я бы решил эту проблему:

 Place the letters from the first string of the array into a list
for each letter in the list{
    count the occurrences of the letter
    for each string in the array{
        count the occurrences of the letter
        if the letter occurs in the list more often than in the string{
            decrease occurrence of letter in list to match letter in string
        }
    }
}
  

Надеюсь, это поможет!

Ответ №4:

Немного измененная версия:

 public List<String> commonChars01(String[] A) {
    int[][] lowerCase = new int[26][A.length];
    
    for(int i = 0 ; i< A.length ; i  ){
        for(int j = 0; j < A[i].length(); j  ) {
            lowerCase[A[i].charAt(j) -'a'][i]   ;
        }                        
    }        
  
    List<String> list = new ArrayList<>();
    
    for (int i = 0; i < 26; i  ) { 
        // all the elements of the array should be equal
        long count = IntStream.of(lowerCase[i])
                .boxed().distinct().count();
        
        // [0, 0, 0] should fail, hence sum should be greater than or equal to 3.
        int sum = IntStream.of(lowerCase[i])
                .boxed().reduce(0, (a,b) -> a   b); 
                
        if ( sum >= 3 amp;amp; count == 1) {
            int timesRepeated = lowerCase[i][0];
            while (timesRepeated != 0) {
                list.add(Character.toString((char)(i   'a')));
                timesRepeated--;
            }
        }
    }        
    
    return list;
}
  

Ответ №5:

попробуйте ниже —

  public List<String> commonChars(String[] words) {

    List<String> ans = new ArrayList<>();
    int wordNums = words.length;
    int[][] charNums = new int[wordNums][26];
    for (int i = 0; i < wordNums; i  ) {
        for (int j = 0; j < words[i].length(); j  ) {
            charNums[i][words[i].charAt(j) - 'a']  =1;
        }
    }
    for (int i = 0; i < 26; i  ) {
        int j = 0;
        int count = Integer.MAX_VALUE;
        for (; j < wordNums; j  ) {
            if(charNums[j][i] == 0 ){
                count = 0;
                break;
            }
            count = Math.min(count, charNums[j][i]);
        }
        for(int k = 0;k<count;k  ){
            ans.add(String.valueOf((char) (i   'a')));
        }
    }
    return ans;
}