一點刷LeetCode題的感想

LeetCode 題集感想

Q1.Two Sum

題目:給定一個數組{2,3,5,7},以及一個目標值target,要求找出兩個能使為target的集合元素的下標,并按下標小的在前排序出來。

思路:

方法1. 使用二重循環掃描數組,找到i 和 j的和為target,再找出輸出下標

超時

方法2. 使用一個map(用Java的HashMap),按<數組元素,下標>存入map,然后對每個數組元素遍歷,紀錄下target減去數組元素的值leftNum,直接在這個map里面找到key為leftNum的,取出value,就是它的序號。這樣數組的index和這個value就是兩個下標值,比較大小,輸出

通過

官方方法:

O(n2) runtime, O(1) space – Brute force:

The brute force approach is simple. Loop through each element x and find if there is another value that equals to target – x. As finding another value requires looping through the rest of array, its runtime complexity is O(n2).

O(n) runtime, O(n) space – Hash table:

We could reduce the runtime complexity of looking up a value to O(1) using a hash map that maps a value to its index.

Q56.Merge Intervals

題目:給定一系列區間,如[1,3],[2,4],[5,6],讓你講所有區間的重疊區間合并并輸出,如前者輸出[1,4],[5,6]

思路:

方法1. 先對這個區間的左值進行排序,由小到大,形成新的區間集合,然后分情況討論(三種):1.如果前一個區間右值比后一個區間左值小,則直接存入結果數組。2.else1的情況下,而且前一個區間的右值比后一個區間的右值小,合并,只保留前一個區間的左值和后一個區間的右值。3.else2的情況下,前一個區間的右值比后一個區間的右值大,保留大的。最后別忘了把最后一組區間也加入到結果數組(沒有向后比較了)

通過

Q2.Add Two Numbers

方法1.

Q3.

Q4.

Q62.Unique Paths

給定一個m*n的方塊路徑,從左上角起點起,到右下角終點,只允許向右或者向下移動,問有多少種走法。

方法1. 看清本質,這個題實際上可以看作一個組合數求值。總共可以向右移動m-1種方法,向下移動n-1種方法。由于只允許向右向下一種,而且一定最后和起來是要走完最長的那一條(舉個例子,m>n,則最后一定把所有m-1個向右走的方法都會用一遍),所以,當m>n,就是求C(m-1+n-1)(m-1);n>=m就是球C(m-1+n-1)(n-1)

通過

136.Single Numble

一個數組,除了一個元素外,其它元素都重復2遍,找出那個元素

方法1. 利用異或的性質 ab;ab 異或運算表00=0;01=1;所以直接可以用0來異或一次得到真實值,異或兩次結果不變,所以直接對數組每個元素和初始為0的result異或即可。

141.Linked List Cycle

判斷一個鏈表是否存在環

方法1. 利用一個"快慢指針",即有兩個指針指向頭節點,一個快指針每次next兩次,一個每次next一次,使用while循環,只要存在一個環,必然經過一輪的循環下,一定會相遇。反之,不存在環,一定不會相遇。時間復雜度為O(n)

通過

208.Implement Trie (Prefix Tree)

實現一個字典樹

字典樹:一個26叉樹,每個結點代表一個字母,value存一個bool值,代表是否存在這個字母。如果對一個單詞進行查找,那么它只需要O(n)的時間,插入的時候也是O(n)。

方法1. 直接貼代碼吧:

class TrieNode {
public:
    // Initialize your data structure here.
    TrieNode() {
        for (int i = 0;i < MAX_NODE;i++) {
            next[i] = 0;
        }
        haveValue = false;
    }
    static const int MAX_NODE = 26;
    TrieNode* next[MAX_NODE];
    bool haveValue;//true repreasent have this character
};

class Trie {
public:
    Trie() {
        root = new TrieNode();
    }

    // Inserts a word into the trie.
    void insert(string s) {
        TrieNode* start = root;
        for (int i = 0;i < s.length();i++) {
            int index = s[i] - 'a';
            if (start->next[index] == 0){
                start->next[index] = new TrieNode();//new character at this node.and go on for next character
            }
            start = start->next[index];
        }
        start->haveValue = true;
    }

    // Returns if the word is in the trie.
    bool search(string key) {
        TrieNode* start = root;
        for (int i = 0;i < key.length();i++) {
            int index = key[i] - 'a';//start with character
            if (start->next[index] == 0){
                return false;
            }
            start = start->next[index];
        }
        return start && start->haveValue;//entire word
    }

    // Returns if there is any word in the trie
    // that starts with the given prefix.
    bool startsWith(string prefix) {
        TrieNode* start = root;
        for (int i = 0;i < prefix.length();i++) {
            int index = prefix[i] - 'a';
            if (start->next[index] == 0){
                return false;
            }
            start = start->next[index];
        }
        return start;//don't need complete all the character
    }

private:
    TrieNode* root;
};

// Your Trie object will be instantiated and called as such:
// Trie trie;
// trie.insert("somestring");
// trie.search("key");

通過

206. Reverse Linked List

就是簡單的反轉鏈表,要求有迭代和遞歸兩種解法

1.迭代法

#include <iostream>
using namespace std;


struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if (head == NULL){return NULL;}
        ListNode* prev = head;
        ListNode* current = head->next;
        ListNode* next;
        while (current) {
            next = current->next;
            current->next = prev;
            prev = current;
            current = next;
        }
        head->next = NULL;
        head = prev;
        return head;
    }
};

2.遞歸法

#include <iostream>
using namespace std;


struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head == NULL){
            return NULL;//fuck
        }
        if(head->next == NULL){
            return head;//stop
        }
        ListNode* next = head->next;//head will stay here
        ListNode* start = reverseList(next);
        head->next = NULL;
        next->next = head;
        return start;
    }
};
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 背景 一年多以前我在知乎上答了有關LeetCode的問題, 分享了一些自己做題目的經驗。 張土汪:刷leetcod...
    土汪閱讀 12,776評論 0 33
  • 她叫Alice,1989年被發現,從1992年開始被追蹤錄音。在其他鯨魚眼里,Alice就像是個啞巴。她這么多年來...
    歌者與貓Alice閱讀 410評論 0 0
  • 1、曼德拉的一句名言: “如果天空是黑暗的,那就摸黑生存;如果發出聲音是危險的,那就保持沉默;如果自覺無力發光的,...
    嬉笑怒罵皆生活閱讀 320評論 0 0