算法小平常-02

【160】相交鏈表

又是要求要空間複雜度爲O(1)
第一種解法:時間複雜度和空間複雜度都是O(n)
給headA循環添加一個標記,而後去循環headB 判斷headB是否有被標記過的節點,若是有則爲相交節點,沒有則返回NULLnode

function getIntersectionNode
(headA, headB) {
    while(headA) {
        headA.flag = true
        headA = headA.next
    }
    while(headB) {
        if (headB.flag) return headB
        headB = headB.next
    }
    return null
};

第二種解法:本題主要是考察雙指針的用法吧。若是A、B相交,那麼A、B自相交節點日後的鏈表是一致的。
咱們能夠嘗試消除 A、B 鏈表的長度差,從數量相等的位置開始,判斷是否有相同節點,如有相同則是兩鏈表相交,返回第一個相同節點 便可。不然返回 null ,兩鏈表不相交。
時間複雜度:O(n)數組

空間複雜度:O(1)this

var getIntersectionNode = function(headA, headB) {
    // 清除高度差
    let pA = headA, pB = headB
    while(pA || pB) {
        if(pA === pB) return pA
        pA = pA === null ? headB : pA.next
        pB = pB === null ? headA : pB.next
    }
    return null
};

【206】反轉一個單鏈表

要求用遞歸和迭代兩種方法來處理
第一種方法迭代法:
時間複雜度:O(n)
空間複雜度:O(1)指針

function reverseList(head) {
    if(!head || !head.next) return head
    var prev = null, curr = head
    while(curr) {
        // 用於臨時存儲 curr 後繼節點
        var next = curr.next
        // 反轉 curr 的後繼指針
        curr.next = prev
        // 變動prev、curr 
        // 待反轉節點指向下一個節點 
        prev = curr
        curr = next
    }
    head = prev
    return head
};

第二種方法:遞歸法
時間複雜度:O(n)
空間複雜度:O(n)code

function reverseList(head) {
    if(!head || !head.next) return head
    var next = head.next
    // 遞歸反轉
    var reverseHead = reverseList(next)
    // 變動指針
    next.next = head
    head.next = null
    return reverseHead
};

[217]給定一個整數數組,判斷是否存在重複元素

本題主要考察的應該是Set吧
方法一:
最開始想了一個最笨的方法,暴力法,兩層循環挨個比較,超級沒有技術含量,其實還能夠先排序,但也不是最簡單的解法。排序

/**
 * @param {number[]} nums
 * @return {boolean}
 */
var containsDuplicate = function(nums) {
    for(var i = 0; i < nums.length; i++){
        for(var j = 0; j < nums.length; j++){
            if(nums[i] == nums[j] && i != j){
                return true;
            }
        }
    }
    return false;
};

方法二:參考了題解用一行代碼搞定
set 去重 而後比較大小遞歸

var containsDuplicate = function(nums) {
    return !(nums.length === new Set(nums).size);
};

【235】二叉搜索樹的最近公共祖先:給定一個二叉搜索樹,找到該樹中兩個指定節點的最近公共祖先。

而後第一個疑問點就是對最近公共祖先的定義:百度百科中最近公共祖先的定義爲:「對於有根樹 T 的兩個結點 p、q,最近公共祖先表示爲一個結點 x,知足 x 是 p、q 的祖先且 x 的深度儘量大(一個節點也能夠是它本身的祖先)。」
題解:利用二叉搜索樹的特色。大小規律能夠採用遞歸法解題get

var lowestCommonAncestor = function(root, p, q) {
    if(root == null){return root}
    if(p.val < root.val && root.val > q.val){
       return lowestCommonAncestor(root.left, p, q);
    }
    if(p.val > root.val && root.val < q.val){
       return lowestCommonAncestor(root.right, p, q);
    }
    return root;
};

[2]兩數相加

給的是兩個非空的鏈表,且按照逆序方式存儲,相加後返回一個鏈表也是逆序存儲。it

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */


var addTwoNumbers = function(l1, l2) {
    var node = new ListNode();
    let temp = node , sum , n = 0
    while(l1 || l2){
        const n1 = l1 ? l1.val : 0
        const n2 = l2 ? l2.val : 0
        sum = n1 + n2 + n
        temp.next = new ListNode( sum % 10 )
        temp = temp.next
        n = parseInt( sum / 10 )
        if(l1) l1 = l1.next
        if(l2) l2 = l2.next
    }
    if( n > 0 ) temp.next = new ListNode(n)
    return node.next
};
相關文章
相關標籤/搜索