조건:

  • 1 <= words.length <= 20
  • 1 <= words[i].length <= 100
  • words의 각 원소는 대문자와 소문자의 혼용으로 이루어져 있습니다.

의역: 문자열들의 배열 words가 주어질 때 해당 문자열에서 미국식 키보드 기분 한 행의 키만 사용해서 만든 문자열들을 배열로 만들어 반환해라. 

 

미국식 키보드:

  • 첫 번째 행: "qwertyuiop",
  • 두 번째 행: "asdfghjkl", 
  • 세 번째 행: "zxcvbnm".

의역: 첫 번째 예시에서는 Alaska와 Dad 만이 2번째 행의 문자들로 구성되어 있기에 저 둘이 반환되었으며

두 번째 예시에서 omk는 첫 번째 두 번째 세 번째 모든 행의 문자들로 구성되어 있기에 빈 공간을 반환합니다.

세 번쨰 예시에서는 words의 원소 모두 2번째 행의 문자들로 구성되어 있기에 words 그대로를 반환합니다.

 

풀이: 

1. 정규식 이용

class Solution {
    // 시간 복잡도O(n*String.matches()) 공간복잡도 O(1)
    public String[] findWords(String[] words) {
        List<String> ans = new ArrayList<String>();
        // [a|b]* 는 a 또는 b가 0번 이상 반복되어 구성된 문자열임을 의미한다.
        for(int i=0;i<words.length;i++){
            if(words[i].matches("[q|Q|w|W|e|E|r|R|t|T|y|Y|u|U|i|I|o|O|p|P|]*")
            ||words[i].matches("[a|A|s|S|d|D|f|F|g|G|h|H|j|J|k|K|l|L]*")
            ||words[i].matches("[z|Z|x|X|c|C|v|V|b|B|n|N|m|M]*"))
                ans.add(words[i]);
        }
        return ans.toArray(new String[ans.size()]);
    }

}

1-1. (한 줄로 줄인 코드)

toLowerCase()를 통해 대소문자 구별을 없애고  | 조건을 추가하여 한 줄로 정리된 모습 

Stream.of(array): 지정된 array를 바탕으로 Stream 객체를 만듭니다.

Stream.filter(람다식): 람다식의 조건을 바탕으로 Stream 객체의 정보를 정리합니다.

String.mathch(정규식): 해당 정규식과 동일한 문자열이면 true 아니면 false를 리턴 합니다.

Stream.toArray(Type[]::new)는 Stream을 Type의 배열로 변환합니다.

public String[] findWords(String[] words) {
    return Stream.of(words).filter(s -> s.toLowerCase().matches("[qwertyuiop]*|[asdfghjkl]*|[zxcvbnm]*")).toArray(String[]::new);
}

2. Set 자료구조 활용 (브루트 포스)

class Solution {
        public String[] findWords(String[] words){
        ArrayList<String>list=new ArrayList<>();

        // mask로 사용할 set 초기화
        String p="qwertyuiop";
        HashSet<Character>a=new HashSet<>();
        for(int i=0;i<p.length();i++){
            a.add(p.charAt(i));
        }
        String q="asdfghjkl";
        HashSet<Character>b=new HashSet<>();
        for(int i=0;i<q.length();i++){
            b.add(q.charAt(i));
        }
        String r="zxcvbnm";
        HashSet<Character>c=new HashSet<>();
        for(int i=0;i<r.length();i++){
            c.add(r.charAt(i));
        }
        
        int j=0;
        for(int i=0;i<words.length;i++){
            String words2=words[i].toLowerCase();
            if(a.contains(words2.charAt(0))){
                for(j=1;j<words2.length();j++){
                    if(!a.contains(words2.charAt(j))){
                        break;
                    }
                }
                if(j==words[i].length()){
                    list.add(words[i]);
                }
            }
            else  if(b.contains(words2.charAt(0))){
                for(j=1;j<words2.length();j++){
                    if(!b.contains(words2.charAt(j))){
                        break;
                    }
                }
                if(j==words2.length()){
                    list.add(words[i]);
                }
            }
            else if(c.contains(words2.charAt(0))){
                for( j=1;j<words2.length();j++){
                    if(!c.contains(words2.charAt(j))){
                        break;
                    }
                }
                if(j==words2.length()){
                    list.add(words[i]);
                }
            }
        }
        return list.toArray(new String[list.size()]);
    }
}

메모: 더 간결하게 줄인다고 해당 코드가 무조건 효율적이지는 않다.

 

링크: https://leetcode.com/problems/keyboard-row/

+ Recent posts