LeetCode經典題目筆記(一)

一、求字符串的最長無重複字符子串的長度。
解法:動態規劃。優化方案爲:在查找與當前字符相同的字符位置時,可以用一個循環遍歷之前的子串,也可以用hash表直接查找,更省時間。
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int len = s.size(),start = 0;
        if (s.empty()||len == 0)
            return 0;
        int dp[len+1] = {0};
        vector<int> hash(256,-1);
     for (int i = 0;i < len;i++) {
            if (hash[s[i]] >= start)
                start = hash[s[i]]+1;
            hash[s[i]] = i;
            dp[i+1] = max(i-start+1,dp[i]);
        }
        return dp[len];
    }
};

二、字符串轉整數
解法:第一個非空格字符之前的空格忽略;第一個非空格字符是+或-則做相應標記;從第一個非空格字符開始遍歷字符串,遇到數字則按規律疊加起來,遇到非數字字符則停止遍歷。
class Solution { 
public
   int myAtoi(string str) { 
       int positive = 1,i = str.find_first_not_of(' '); 
       long sum = 0
       if (str[i] == '+' || str[i] == '-') 
            positive = str[i++] == '-'?-1:positive; 
       while (isdigit(str[i])) { 
            sum = (sum<<1) + (sum<<3) + str[i++]-'0'; 
           if (sum > INT_MAX) 
               return positive == 1?INT_MAX:INT_MIN; 
        }
       return positive*sum; 
    }
};

三、判斷一個整數是不是迴文序列
解法:
class Solution {
public
:
    bool isPalindrome(int x) {
        if (x>0 && x%10 == 0)
            return false;
        int sum = 0;
        while (sum < x) {
            sum = (sum<<1)+(sum<<3)+x%10;
            x /= 10;
        }
        if (sum == x||sum/10 == x)
            return true;
        else
            return false;
    }
};

四、求兩個已排序數組的中位數
解法:二分查找。
①中位數將所有數據分成個數相等的兩個部分,且其中一部分全部大於另一部分;
②同時在兩個有序數組中查找合適的劃分點,由於要保證劃分出的兩部分數據個數相等,所以只在其中一個數組的下標中進行二分搜索劃分點i,從而確定出另外一個數組中的劃分點j;
③爲了確保由i推導出的j>=0,需選擇長度較小的數組進行二分搜索,這樣能確保j合法;
④兩個劃分點左側的數據爲較小的一半,右側爲較大的一半,所以判斷搜索出的劃分點是否合法的條件爲:較小一半的最大值小於較大一半的最小值。否則更新二分搜索的範圍。
class Solution {
public
:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int len1 = nums1.size(),len2 = nums2.size(),half_len = (len1+len2+1)/2;
        if (len1 > len2) 
            return findMedianSortedArrays(nums2,nums1);
        int start = 0,end = len1,i,j,numleft,numright;
        while(start <= end) {
            i = (start+end)/2;
            j = half_len-i;
            if (i>0&&j<len2&&nums1[i-1] > nums2[j]) 
                end = i-1;
            else if (j>0&&i<len1&&nums2[j-1] > nums1[i])
                start = i+1;
            else {
                if (i == 0) {
                    numleft = nums2[j-1];
                }
                else if (j == 0) {
                    numleft = nums1[i-1];
                }
                else {
                    numleft = max(nums1[i-1],nums2[j-1]);
                }
                break;
            }
        }
        if (j == len2 && len1 != 0) numright = nums1[i];
        else if (i == len1 && len2 != 0) numright = nums2[j];
        else numright = min(nums1[i],nums2[j]);
        return (len1+len2)%2 == 1?(double)numleft:(numleft+numright)/2.0;
    }
};

五、求字符串的最長迴文子串
解法:遍歷字符串,以每個字符爲中間點向兩邊擴展比較,記錄下最長的迴文子串長度和起始位置即可。遇到連續相同的字符要跳過,他們一定包含在同一個迴文中。
class Solution {
public
:
    string longestPalindrome(string s) {
        int len = s.size();
        if (len < 2)
            return s;
        int mid = 0,maxLen = 1,start = 0;
        while (mid < len) {
            if (len-mid <= maxLen/2)
                break;
            int left = mid,right = mid;
            while (right < len-1 && s[right+1] == s[right])
                ++right;
            mid = right+1;
            while (left > 0 && right < len-1 && s[left-1] == s[right+1]) {
                --left;
                ++right;
            }
            if (right-left+1 > maxLen) {
                maxLen = right-left+1;
                start = left;
            }
        }
        return s.substr(start,maxLen);
    }
};

六、刪除鏈表中某個結點
解法一:循環到鏈表尾,依次將結點值向前複製一步。
class Solution {
public
:
    void deleteNode(ListNode* node) {
        while (node->next->next) {
            node->val = node->next->val;
            node = node->next;
        }
        node->val = node->next->val;
        delete node->next;
        node->next = NULL;
    }
};
解法二:直接將下一個結點的內容全部複製到當前結點,再刪除下一個結點。
class Solution {
public
:
    void deleteNode(ListNode* node) {
        ListNode* next = node->next;
        *node = *next;
        delete next;
    }
};

七、求小於正整數n的素數個數




class Solution {
public
:
    int countPrimes(int n) {
        vector<int> hmap(n,1);
        if (n < 3)
            return 0;
        int upper = sqrt(n);
        for (int i = 2;i <= upper;++i) {
            if (hmap[i] == 0)
                continue;            
        for (int non_prime = i*i;non_prime < n;) {
                hmap[non_prime] = 0;
                non_prime += i;
            }
        }
        int count = 0;
        for (int k = 2;k < n;++k)
            if (hmap[k] == 1)
                ++count;
        return count;
    }
};

八、找到二叉樹中所有路徑

注意:題中的""不需要輸出,""只代表字符串。

解法:遞歸。
class Solution {
public
:
    void binaryTreePaths(vector<string>& result, TreeNode* root, string t) {
        if (!root->left && !root->right) {
            result.push_back(t);
            return;
        }

        if (root->left) 
            binaryTreePaths(result, root->left, t + "->" + to_string(root->left->val));
        if (root->right) 
            binaryTreePaths(result, root->right, t + "->" + to_string(root->right->val));
    }

    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> result;
        if (!root) return result;

        binaryTreePaths(result, root, to_string(root->val));
        return result;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章