题目

Excel Sheet Column Title

给定一个正数,求它在excel中对应的标头值。

1 -> A
2 -> B
3 -> C
...
26 -> Z
27 -> AA
28 -> AB 

PS:Excel2003版之前最大是255列,2007版最大是16384列,当然这和题目无关。

思路

这个题目其实是把十进制的数字转化成26进制。想到之前求一个数的二进制是通过不断除2的方式,这个也一样。

只要除以26之后得到商比26大就拿这商除26,并把每次除法的余数保存起来,直到商为0,将余数们反向输出就是26进制表达了。

实现

JavaScript:

/**
 * @param {number} n
 * @return {string}
 */
var convertToTitle = function(n) {
     var cs=[];

    while(n>26){
        if(n%26!==0){
             //将余数对应的字母插入数组头部
            cs.unshift(String.fromCharCode(n%26+64));
            n = Math.floor(n /26);
        }else{
            //如果刚好整除,那么商减1,余数为26
            cs.unshift(String.fromCharCode(90));
            n = Math.floor(n /26) -1;

        }
    }
    cs.unshift(String.fromCharCode(n+64));
    return cs.toString().replace(/\,/g,"");
};

excelcolumntotile

题目

Merge Two Sorted Lists

有两个排序好的链表l1和l2,要求是合并为一个列表,并保持列表有序。

思路

我的想法是先遍历两个链表找到较短的一个,然后把短链表上节点逐个插入到长链表中。

然后在网上看别人的代码,其实不用先找到短链。拿一个链表做基准,将另外一个插入就来,只遍历一次就好了。

实现

JavaScript:

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var mergeTwoLists = function(l1, l2) {
    //定义指针
    var sPointer = l1,lPointer = l2;

    //一些特殊情况的处理
    if(sPointer&&sPointer.val&&lPointer&&lPointer.val===null){
        return sPointer;
    }
    if(sPointer&&sPointer.val===null&&lPointer&&lPointer.val){
        return lPointer;
    }
    if(sPointer&&!lPointer){
        return sPointer;
    }
    if(!sPointer&&lPointer){
        return lPointer;
    }
    if(!sPointer&&!lPointer){
        return null;
    }

     //找到较短链表,逐个插入到长链表中
    while(sPointer){
        if(!lPointer){ //lpointer为null,说明l1>l2
            sPointer = l2;
            lPointer = l1;
            break;
        }
        sPointer = sPointer.next;
        lPointer = lPointer.next;
    }
    if(!sPointer){
        //l1<=l2
        sPointer = l1;
        lPointer = l2;
    }

    //为了保存插入节点previous的位置,创建一个dummy的节点
    var dummy = new ListNode(0);
    dummy.next = lPointer;

    var prePointer = dummy;

    var insertnode = sPointer;
    while(sPointer){
        if(insertnode.val<=lPointer.val){

            prePointer.next = insertnode;
            sPointer = sPointer.next;
            insertnode.next = lPointer;
            //短链的指针后移一位,长链不动
            insertnode = sPointer;
            prePointer = prePointer.next;
        }else{
            if(!lPointer.next){
                lPointer.next = sPointer;
                break;
            }
            //长链后移一位,短链不动
            prePointer =lPointer;
            lPointer = lPointer.next;
        }


    }
    return dummy.next;
};

merge2sortedlists

在requirejs的官网找到这样一段话:
RequireJS loads each dependency as a script tag, using head.appendChild().
RequireJS waits for all dependencies to load, figures out the right order in which to call the functions that define the modules,
then calls the module definition functions once the dependencies for those functions have been called.

翻译过来是:

RequireJS通过head.appendChild()将每一个依赖加载为一个script标签。

等到所有的依赖都加载完成之后,RequireJS计算出模块定义函数的调用顺序。

一旦依赖这些功能的地方被调用时requiredjs会调用这些功能的模块定义。

requirejs是怎么做到模块化的?

requirejs有个loader来保存和监听所有依赖的状态。script标签来加载这些文件,加载成功和失败都会更新依赖的状态。

是否有重复引用?

Requirejs是单例的设计,只要同名的被引入过一次(这里的同名相当于amd define的id)就一直是用这个模块的定义。

为了避免全局污染,遵循AMD的规范,define和export。

理想状况下,每个加载的脚本都是通过define()来定义的一个模块;

但有些”浏览器全局变量注入”型的传统/遗留库并没有使用define()来定义它们的依赖关系,就必须为此使用shim config来指明它们的依赖关系。

JS中通过style来获取元素的样式有时并获取不到,为什么呢?

一个元素的样式由三部分组成,嵌入样式,内联样式和外联样式。

  • 内联样式: 写在标签内的样式,
  • 嵌入样式: 写在和之间,用包住的样式
  • 外联样式: 由标签引入的外部css

document.getElementById(“ID”).style 只可以获取到内嵌样式,也就是写在标签内style属性中定义的样式。

在IE下可以用currentStyle中获取其他样式,但在别的浏览器中不支持。

而火狐,chrome等可以通过getComputedStyle这个方法来获取所有计算过的样式。

getComputedStyle(document.getElementById("ID"))

题目

对于Object来说,其实没有长度的概念,所以也并没有length的属性或者size()的方法来获取。

那如果想要计算这个object中定义了多少属性值呢?(从Ojbect继承过来的不算)

思路

方法1: Object中有hasOwnProperty()的方法,可以判断对象是否有某个特定的属性。
for-in 可以查找object的所有属性。而hasOwnProperty是判断本身对象的属性,不查找原型链的属性,这正好是我们要的。

方法2: Object还有另外一个keys的方法,可以返回所有的keys。

实现

方法1:

 var obj = {a:"1",b:"2",c:"3"},length=0;

 for (var property in obj) {
     if (obj.hasOwnProperty(property)) {
         length++;
     }
 }

console.log(length);

方法2:

var obj = {a:"1",b:"2",c:"3"};       
console.log(Object.keys(obj).length);

题目

Isomorphic Strings

判断两个字符串是否为同型构造的字符串。

比如:

Given “egg”, “add”, return true.

Given “foo”, “bar”, return false.

Given “paper”, “title”, return true.

如果s字符串的字母被替换可以得到t字符串的话,则说明s和t字符串的构造是相同的。

思路

按照同形构造的定义来,如果字母替换可以得到目标字符串,我们先建一个map来存储s和t/t和s字母的对应关系。
然后分别遍历s和t的字符串,只要出现当前字母和map表的字母不匹配的,就说明s和t不是同源的字母。

实现

JavaScript:

/**
 * @param {string} s
 * @param {string} t
 * @return {boolean}
 */
var isIsomorphic = function(s, t) {
    if(s===t){
        return true;
    }else{
        var sArray= s.split(""),tArray = t.split("");
        var map = {};

        for(var i=0;i< sArray.length;i++){
            //找出t和s 字母的匹配关系
            if(!map[tArray[i]]){
                map[tArray[i]] = sArray[i];
            }else{
                //如果当前字母和map中取出的字母不匹配,则返回false
                if(sArray[i]!==map[tArray[i]]){
                    return false;
                }
            }
        }
        //清空map,反向查找匹配关系
        map ={};
        for( i=0;i< tArray.length;i++){
            //找出s和t字母的匹配关系
            if(!map[sArray[i]]){
                map[sArray[i]] = tArray[i];
            }else if(tArray[i]!==map[sArray[i]]){
                //如果当前字母和map中取出的字母不匹配,则返回false
                return false;
            }

        }
        return true;
    }
};

结果

isomorphicstrings

PS

一开始想的是replace的方法,但是后面验证出来发现输入的字符串有各种需要转义的特殊字符(*&$’)。

题目

找出一个数字的二进制中有多少个1

给定一个无符号的整型数字,比如11,它的二进制是1011,所以返回1的个数3.

思路

对二进制进行位操作,每向右移1位和1做位与操作。是1的话计数器加1,直到右移到0截止。

这个方法写得很轻松,但是耗时长。

实现

JavaScript:

/**
 * @param {number} n - a positive integer
 * @return {number}
 */
var hammingWeight = function(n,count) {
    if(!count){
        count = 0;
    }
    if(n&1===1){
        count++;
    }
    if(n>1){
        return hammingWeight(n>>>1,count);
    }else{
        return count;
    }
};

题目

Palindrome Linked List

判断一个单向链表(没有环)是否是回文链表。

要求时间复杂度在O(n),空间复杂度 O(1)

思路

1, 找到链表的中间节点。
2, 反转链表后半部分。
3, 比较前半部分和后半部分的值是否相等
4, 还原现场,将后半部分反转回原貌

查到链表的中间节点

var fPointer = sPointer = midPos= head;
while (fPointer.next) {
    sPointer = sPointer.next;
    fPointer = fPointer.next;
    if(fPointer.next){
        fPointer = fPointer.next;
    }else{
        break;
    }
}
midPos = sPointer;

反转链表

PS: 反转还没有写出来,下面是错误的。

反转链表的方法是从第2个节点到第N个节点,依次逐节点插入到第1个节点(head节点)之后,最后将第一个节点挪到新表的表尾。

我们此时的head是midPos,移动sPointer指针。

fPointer = misPos;
sPointer = sPointer.next;

while(sPointer){
    //暂时保存head.next
    fPointer = midPos.next;
    //将要插入的节点放到head的next
    midPos.next = sPointer;
    //将插入节点的next赋值为前面保存的head.next
    sPointer.next = fPointer;

    //移动sPointer
    sPointer = sPointer.next   
}

实现

将一个数字转换为千分位的金额格式,找了酱一个正则表达式。

var num =12345;
console.log ((num.toFixed(2) + '').replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,'));

解析

一点点来看这个正则式什么意思。

toFixed(2) : 数字保留2位小数。

\d{1,3} : 包含1个或者3个数字的字符串。(为简便表述,这个字符串先记做A)

\d{3} : 包含3个数字

(\d{3})+ : 包含至少1个的3个数字的组合

(.\d*)?$ : 以小数点以及其n位数字为结尾

(\d{3})+(.\d*)?$ : 小数点前至少1个3个数组,小数点后有n为数字的字符串(为简便表述,这个字符串先记做B)

?=(\d{3})+(.\d*)?$ : 找出任何其后紧接指定字符串B的字符串A

/g : 全局匹配

$&, : 当前匹配的字符串,集合上面的,这个匹配字符串为A,并将A后面加个逗号“,”

字面的意思就酱了。

验证

我们举几个例子来验证一下。

假设num 是2位数或1位数,那么字符串B是为空的,不做逗号替换,直接返回;

num是3位数,则B = num,但是字符串A是空的,不做逗号替换,直接返回。

num是4,5位数,B是后三位,A是B前一位,找到这样的A,对A进行逗号替换。然后继续找,发现找不到了。

num是6位数,B = num, 找不到A,继续, B = num的后三位,找到A是B的前一位,加逗号。

num是7位数(1234567),B = num的后六位(234567),A是第一位(1),加逗号,此时结果为(1,234567).

再继续查找,B是567,找到A是4,加逗号,结果为(1,234,567).这就递归num是6为数的情况了。

我们先找字符串B为345.00,然后找到2是满足字符串A的要求的。2后面加逗号。
g 继续找,发现没有了,结果是12,345.00;

话说其实试验下来发现字符串A可以直接是\d{1}

PS:

正则中$1,$2,$3,..$99,代表第1,2,3,…99匹配的字符串。

$’代表当前匹配字符串后面的字符串。
$`代表当前匹配字符串前面的字符串。

比如字符串“Hello,World”, 匹配字符串为”,”的话,$`代表“Hello”,$’代表“World”