leetcode--easy模式(javascript)[doing...]

1、 reverse string

//Example:Given s = "hello", return "olleh".
/**
 * @param {string} s
 * @return {string}
 */
解法一:
var reverseString = function(s) {
    var result="";
    for(var i=1,len=s.length;i<=len;i++){
        result+=s[len-i]
    }
    return result;
};
或者利用js提供的数组的reverse()方法
解法二:
var reverseString = function(s) {
    return s.split("").reverse().join("")
};

关于数组的知识点:http://riny.net/2012/the-summary-of-javascript-string/

2、 Nim Game

You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove the stones.

Both of you are very clever and have optimal strategies for the game. Write a function to determine whether you can win the game given the number of stones in the heap.

For example, if there are 4 stones in the heap, then you will never win the game: no matter 1, 2, or 3 stones you remove, the last stone will always be removed by your friend.

Hint:

If there are 5 stones in the heap, could you figure out a way to remove the stones such that you will always be the winner?
【分析】看清题设很重要,已经提到Both of you are very clever and have optimal strategies for the game.所以我们在分析的时候就不能说通过遍历这种想法看是否存在赢的可能,因为对手也有着足够的智商。如果对手智障的话,那就除了n==4时必输,其它情况都可能赢了。

当n∈[1,3]时,先手必胜。

当n == 4时,无论先手第一轮如何选取,下一轮都会转化为n∈[1,3]的情形,此时先手必负。

当n∈[5,7]时,先手必胜,先手分别通过取走[1,3]颗石头,可将状态转化为n == 4时的情形,此时后手必负。

当n == 8时,无论先手第一轮如何选取,下一轮都会转化为n∈[5,7]的情形,聪明的对手也会将状态转为n==4的情形,此时先手必负。
...

通过以上分析可以得出,n%4!=0时,先手必胜。

/**
 * @param {number} n
 * @return {boolean}
 */
var canWinNim = function(n) {
    return n%4!==0
}

3、Single Number

Given an array of integers, every element appears twice except for one. Find that single one.

【分析】
这个问题其实不难,但它的要求是:Your algorithm should have a linear runtime complexity. 所以像什么嵌套循环的想法要直接pass,最初我看到这要求是一声冷笑的,因为我在很久之前看到过 钩子函数 ,也就是将这些数组中的元素当做一个对象的key,出现次数作为其value。所以代码很快如下:

/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function(nums) {
    var obj = {},
        result;
    for (var i = 0, len = nums.length; i < len; i++) {
        var val = nums[i];
        if (!obj[val]) {
            obj[val] = 1;
        } else {
            obj[val] = 2;
        }
    }
    for (var item in obj) {
        if (obj[item] === 1) {
            result = item;
            return parseInt(result);
        }
    }
};

复杂度还是O(n)的,但是2n,效率超过了86%左右,然后去网上查查看还有啥解法,然后就发现了如下让我大吃一惊的代码:

/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function(nums) {
    var result = 0;
    for (var i = 0,len=nums.length; i

他的效率超过了100% ! 是的,他用了XOR运算,不需要额外内存。因为A XOR A = 0,且XOR运算是可交换的,所以对于实例{2,1,4,5,2,4,1}就会有这样的结果:

(2^1^4^5^2^4^1) => ((2^2)^(1^1)^(4^4)^(5)) => (0^0^0^5) => 5

这些基础我们真的是走着走着就忘了。。。

4、Add Digits

Given a non-negative integer num, repeatedly add all its digits until the result has only one digit.

For example:

Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it.

【分析】如果问题是这样,这是个很直观的循环搞定的问题。然而后面题目中又加了一句:Could you do it without any loop/recursion in O(1) runtime?------Excuse me ???!!!

先来个循环压压惊:

/**
 * @param {number} num
 * @return {number}
 */
var addDigits = function(num) {
    var val=0;
    while(num>=10){
        val=parseInt(num/10);
        num=num%10;
        num+=val;
    }
    return num;
};

既然题目问是否可以不用循环,那么首先就要想这里面应该是有规律的。打印下前30个数看看:

显然9个一循环,所以是对9取余的结果,但是,对于9的倍数对9取余为0,结果就不对了,所以修正为:

var addDigits = function(num) {
    return (num-1)%9+1
};

你可能感兴趣的:(leetcode--easy模式(javascript)[doing...])