My JavaScript solution - how can I improve?


  • 3
    F

    Here's my JavaScript solution. My solution ran in 86ms and was better that 11% of other submissions. How can I improve?

    /**
     * @param {string[]} words
     * @return {string[]}
     */
    var findWords = function(words) {
        var resultWords = [];
        for (var i = 0; i < words.length; i++) {
            if(isSameRow(words[i]))
                resultWords.push(words[i]);
        }
        return resultWords;
    };
    
    /**
     * @param {string} word
     * @return {bool}
     */
    var isSameRow = function(word) {
        var rowNumber = getKeyboardRow(word.charAt(0));
        for (var i = 1; i < word.length; i++) {
            if(getKeyboardRow(word.charAt(i)) !== rowNumber)
                return false;
        }
        return true;
    };
    
    /**
     * @param {string} char
     * @return {number}
     */
    var getKeyboardRow = function(char) {
        var currentChar = char.toLowerCase();
        var charRowMap = {
            "q": 1, "w": 1, "e": 1, "r": 1, "t": 1, "y": 1, "u": 1, "i": 1, "o": 1, "p": 1,
            "a": 2, "s": 2, "d": 2, "f": 2, "g": 2, "h": 2, "j": 2, "k": 2, "l": 2,
            "z": 3, "x": 3, "c": 3, "v": 3, "b": 3, "n": 3, "m": 3
        }
        return charRowMap[currentChar];
    };
    

  • 0
    A
    var findWords = (words) => {
      const Map = {q:1,w:1,e:1,r:1,t:1,y:1,u:1,i:1,o:1,p:1,a:2,s:2,d:2,f:2,g:2,h:2,j:2,k:2,l:2,z:3,x:3,c:3,v:3,b:3,n:3,m:3}
      let temp = 0
      let RightWords = []
      words.forEach((item) => {
        if (item.length == 1) RightWords.push(item)
        temp = Map[item[0].toLowerCase()]
        for (let i = 1,length = item.length;i < length; i++) {
          if (temp != Map[item[i].toLowerCase()]) {
            return
          }
          if (i == item.length - 1) {
            RightWords.push(item)
          }
        }
      })
      return RightWords
    }
    

    this is my solution


  • 0
    U
    This post is deleted!

  • 0
    U

    This is my solutions using JavaScript.

    The first one runtime beats 77.16% of javascript submissions. By the words. I use functions in the loop.(The markdown editor give me a worn like 'don't make functions in the loop')

    var findWords = function(words) {
    	let obj = {
    		top: 'qwertyuiop',
    		center: 'asdfghjkl',
    		bottom: 'zxcvbnm',
    	};
    	let arr = [];
    	for (let val of words) {
    		let vals = val.toLowerCase();
    		let target;
    		let alpha = vals.split('');
    		for (let v of Object.values(obj)) {
    			if (~v.indexOf(vals[0])) target = v;
    		}
    		if (alpha.every(value => ~target.indexOf(value))) arr.push(val);
    	}
    	return arr;
    };
    

    The seconds one runtime beats 35.25% of javascript submissions. I do not use functions in the loop.

    var findWords = function(words) {
    	let obj = {
    		top: 'qwertyuiop',
    		center: 'asdfghjkl',
    		bottom: 'zxcvbnm',
    	};
    	let arr = [];
    	for (let val of words) {
    		let vals = val.toLowerCase();
    		let target;
    		let record = '';
    		for (let v of Object.values(obj)) {
    			if (~v.indexOf(vals[0])) target = v;
    		}
    		for (let alpha of vals) {
    			if (~target.indexOf(alpha)) record += '1';
    		}
    		if (record.length === vals.length) arr.push(val);
    	}
    	return arr;
    };
    

    `


  • 1
    F

    This is my solution, sometime it can beat 100%, but sometime it just can beat 4%. I try many times, and found the percent number changes everytime. So I don't know whether the number given by the website does make sense. ╮(╯▽╰)╭

    var findWords = function(words) {
        var wordsNew=[],result=[],keyboard=["qwertyuiop","asdfghjkl","zxcvbnm"];
        words.forEach(function(ele,index){wordsNew[index]=ele.toLowerCase()});
        
        wordsNew.forEach(function(ele,index){
            for(var j=0;j<3;j++){
                var flag1=0;
                for(var i=0;i<ele.length;i++){
                        if(keyboard[j].indexOf(ele[i])==-1){flag1++}
                    }
                if(flag1===0){result.push(words[index])}
            }
        });
        return result;
    };
    

  • 0
    F

    That's good enough. To save memory and reduce gcs you could move that charRowMap outside of the function definition (so unique instance shared instead or recreating it on every call).

    You could also return words.filter(isSameRow) from your main function, which is shorter and more elegant.


  • 0
    C

    I think my way is sample to understand

    var findWords = function(words) {
        var arr = [];
        var rowArr = ['qwertyuiop','asdfghjkl','zxcvbnm'];
        for(var i=0;i<words.length;i++){
            for(var k=0;k<rowArr.length;k++){
                for(var j=0;j<words[i].length;j++){
                    if(rowArr[k].indexOf(words[i][j].toLowerCase()) === -1 ){  // 一开始忘了转换为小写形式比较
                        break;
                    }
                    if(j === words[i].length-1){
                        arr.push(words[i])
                    }
                }
            }
        }
        return arr
    };
    

  • 0
    W

    I am a geniuses

    var findWords = function(words) {
        var keyboard=['qwertyuiop','asdfghjkl','zxcvbnm'];
        var result=[];
        for(var i=0;i<words.length;i++){
            var letters = words[i].toLowerCase().split('');
            var flag = true;
            for(var j=0;j<3;j++){
                if(keyboard[j].indexOf(letters[0]) !==-1){
                    for(var k=1;k<letters.length;k++){
                        if(keyboard[j].indexOf(letters[k]) ===-1){
                            flag = false;
                            break;
                        }
                    }
                }
            }
            if(flag){
                result.push(words[i]);
            }
        }
        return result;
    

  • 0
    T

    @Wangqinxiao Why don't you use filter instead of pushing into a new array? My solution without regex looked like that:

    const rows = [
        'qwertyuiop',
        'asdfghjkl',
        'zxcvbnm'
    ]
    
    const findRow = (char) => {
        for (var idx in rows) {
            if (rows[idx].includes(char)) return idx
        }
        return -1
    }
    var findWords = function(words) {
        return words.filter((word) => {
            word = word.toLowerCase()
            for (let idx = 1; idx < word.length; ++idx) {
                if (findRow(word[idx]) === -1 || findRow(word[idx]) !== findRow(word[idx - 1])) {
                    return false
                }
            }
            
            return true
        })
    };
    

    But of course it's easier with regex, oneliner:

    var findWords = function(words) {
        return words.filter((word) => /^([qwertyuiop]*|[asdfghjkl]*|[zxcvbnm]*)$/i.test(word))
    };
    

Log in to reply
 

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