8 lines simple Java


  • 132
    public boolean wordPattern(String pattern, String str) {
        String[] words = str.split(" ");
        if (words.length != pattern.length())
            return false;
        Map index = new HashMap();
        for (Integer i=0; i<words.length; ++i)
            if (index.put(pattern.charAt(i), i) != index.put(words[i], i))
                return false;
        return true;
    }
    

    I go through the pattern letters and words in parallel and compare the indexes where they last appeared.

    Edit 1: Originally I compared the first indexes where they appeared, using putIfAbsent instead of put. That was based on mathsam's solution for the old Isomorphic Strings problem. But then czonzhu's answer below made me realize that put works as well and why.

    Edit 2: Switched from

        for (int i=0; i<words.length; ++i)
            if (!Objects.equals(index.put(pattern.charAt(i), i),
                                index.put(words[i], i)))
                return false;
    

    to the current version with i being an Integer object, which allows to compare with just != because there's no autoboxing-same-value-to-different-objects-problem anymore. Thanks to lap_218 for somewhat pointing that out in the comments.


  • 7
    C

    I use the similar thought while the big test case gives wrong answer error and I dont know why.

    public class Solution {
        public boolean wordPattern(String pattern, String str) {
            String[] strs = str.split(" ");
            HashMap<String, Integer> mapstr = new HashMap<String, Integer>();
            HashMap<Character, Integer> mapc = new HashMap<Character, Integer>();
            if(pattern.length() != strs.length) return false;
            for(int i = 0; i < pattern.length(); i++){
                char tmpc = pattern.charAt(i);
                String tmpstr = strs[i];
                if((mapc.containsKey(tmpc) ^ mapstr.containsKey(tmpstr))
                    ||(mapc.containsKey(tmpc) && mapstr.containsKey(tmpstr) && mapc.get(tmpc) != mapstr.get(tmpstr))) return false;
                mapc.put(tmpc, i);
                mapstr.put(tmpstr, i);
            }
            return true;
        }
    }
    

  • 5

    It's because you use != to compare the Integer objects.


  • 0
    C

    Got it, thank you


  • 1
    C

    Very concise and clear, thank you! For those who might not know, putIfAbsent is a new function introduced in SDK 1.8.


  • 0

    Nice ^-ing of the booleans, btw. But rethink the following line, you're doing an unnecessary check there.


  • 0

    And nice approach, comparing the previous time the letter/word appeared.


  • 0
    C

    Aha, yes this approach feels concise. Thank you Stefan you always deliver nice catch.


  • 0

    Haha, actually only now did I realize how extremely close our approaches are and that I can simply replace my putIfAbsent with just put, so now it's even nicer. I updated it in my question. Thanks! :-)


  • 0

    Heh, I actually replaced that now, though it's still in the explanation.


  • 0
    C

    Even better using put. :-) Didn't know it works that way. Appreciate the new update!


  • 10

    Yes, only few people seem to know that Map.put and Set.add return something. I often see unnecessary if (!map.containsKey(...)) or if (!set.contains(...))before putting or adding :-P


  • 0
    C

    Now it's really concise as hell, nice feature of return value of put!!


  • 0
    C

    Aha, like me : P


  • 0

    Is there an issue for test case: "abc" "b c a" ?


  • 5

    @在线疯狂 You mean because there are letters that are also words, so the map might confuse them?

    I was hoping someone would notice this and bring it up. Well done :-)

    But no, it's no problem. The map distinguishes keys with equals, and Character and String objects aren't equals. Try adding this, for example. It will have no effect:

        String s = "x";
        Character c = s.charAt(0);
        if (c.equals(s) || s.equals(c))
            throw new RuntimeException();

  • 0

    Aha, you are right! Class type of objects is also compared in Java, I almost forgot it!


  • 0
    X

    exactly me.... this solution is impressive of using returning value of put...ty


  • 0
    W

    very impressive usage of return value of put().


  • 0
    C
       public boolean wordPattern(String pattern, String str) {
               if(str==null||str.length()==0)return  false;
    	        String[] words=str.split(" ");
    	        if(pattern.length()!=words.length)return false;
    	        HashMap<String,String> map = new HashMap<String,String>();
    	        for(int i=0;i<words.length;i++){
    	        	if(map.containsKey(pattern.charAt(i)+"")){
    	        		if (!map.get(pattern.charAt(i)+"").equals(words[i])) {
    						return false;
                           }
    	        }else if(map.containsKey(words[i])){
    	        	if (!map.get(words[i]).equals(pattern.charAt(i)+"")) {
    					return false;
                       }
    	        	}else{
    		        	map.put(pattern.charAt(i)+"", words[i]);
    		        	map.put(words[i], pattern.charAt(i)+"");
    	        	}
    	        }
    	        return true;
    	    
        }
    

    validate the mapping relation both ways.


Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.