LeetCode Note

NO.3無重複的最長子串

思路:一個數組保存a-z上一個出現字母的位置,一旦出現重複回到上次出現後一個位置。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s=="")return 0;
        else if(s==" ")return 1;
        int length =0;
        int A[130]={0};
        int count =0;
        for(int i=0;i<s.size();i++){
            if(A[s[i]]==0){
                A[s[i]]=i+1;
                count++;
            }else{
                length = max(length,count);
                i=A[s[i]]-1;
                memset(A,0,130*sizeof(int));
                count=0;
         
            }
        }
        length=max(length,count);
        return length;
    } 
};

NO4.尋找兩個有序數組的中位數

要求:時間複雜度爲O(m+n)

思路:合併兩個有序有數組,取新數組的中間數。

技術點:①合併有序數組;②爲數字分配空間

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int len1 =  nums1.size();
        int len2 = nums2.size();
        int n1=0,n2=0,n=0;
        int len = len1+len2;
        
        int *merge;
        merge = (int *)malloc(len*sizeof(int));
        
        
        while(n1<len1||n2<len2){
            if(n1>=len1)merge[n++]=nums2[n2++];
            else if(n2>=len2)merge[n++] = nums1[n1++];
            else{
                if(nums1[n1]>=nums2[n2])
                    merge[n++]=nums2[n2++];
                else
                    merge[n++]=nums1[n1++];
            }
            
        }
        double ans;
        int t = len/2;
        if(len%2==0){
            ans = (merge[t-1]+merge[t])/2.0;
        }else{
            ans = (double)merge[t];
        }
        
        return ans;
    }
};

NO.7整數反轉

解題關鍵點及Tip:

①注意有無溢出,不止是結果的溢出,在計算的過程中也會出現溢出,所以中間的計算要用long型,得出結果後再判斷是否溢出。

②可用十六進制表示很大的數。如0x7fffffff

class Solution {
public:
    int reverse(int x) {
        int num[33]={0};
        int len=0,flag=0;
        long sum=0;
        int max = 0x7fffffff,min = 0x80000000;
        if(x<0) {
            flag=1;
        }
        while(x!=0){
            sum=sum*10+x%10;
            x/=10;
        }
        if(sum>max||sum<min)return 0;
        if(flag==1 && sum>0){
            return -sum;
        }else{
            return sum;
        }
    }
};

NO.9迴文數

①因爲可能有溢出,所以改爲long long型

class Solution {
public:
    bool isPalindrome(int x) {
        if(x<0)return false;
        else if(x==0) return true;
        else{
            long long sum=0,c=x;
            while(x!=0){
                sum=sum*10+x%10;
                x/=10;
            }
            if(sum==c)
                return true;
            else return false;
        }
    }
};

NO.11盛最多水的容器

思路:從最寬的開始,兩個指針一個指向最左,一個指向最右,寬度越寬面積大概率會較大,但是高度也會影響,將高度較小的那個往裏縮,縮進後進行判斷那個面積更大。

class Solution {
public:
    int maxArea(vector<int>& height) {
        int i=0,j=height.size()-1;
        int h;
        int area =0;
        while(i<j){
            h = min(height[i],height[j]);
            area = max(area,h*(j-i));
            if(height[i]>height[j])j--;
            else i++;
        }
        return area;
    }
};

NO.14最長公共前綴

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        if(strs.size()==0)return "";
        string str1 = strs[0];
        int length =str1.size();
        int xlen = str1.size();
        string prefix = "";
        int j;
        for(int i=0;i<strs.size();i++){
            string temp = strs[i];
            int templen = temp.size();
            int len=min(xlen,templen);
            for(j=0;j<len;j++){
                if(temp[j]!=str1[j]){            
                    break;
                }
            }
            length = min(length,j);
        }
        if(length==0)return "";
        else{
            prefix = str1.substr(0,length);
            return prefix;
        }
    }
};

NO.15三數之和

①排序,sort(vector.begin(),vector.end());②考慮去除重複

NO.20有效的括號

①使用棧,stack<char> a;

class Solution {
public:
    bool isValid(string s) {
        stack<char> a;
        if(s=="")return true;
        a.push(s[0]);
        for(int i=1;i<s.length();i++){
            switch(s[i]){
                case '(':
                case '[':
                case '{':
                    a.push(s[i]);
                    break;
                case ']':
                    if((!a.empty())&&a.top()=='[')a.pop();
                    else a.push(s[i]);
                    break;
                case ')':
                    if((!a.empty())&&a.top()=='(')a.pop();
                    else a.push(s[i]);
                    break;
                case '}':
                    if((!a.empty())&&a.top()=='{')a.pop();
                    else a.push(s[i]);
                    break;
            }
            
        }
        if(a.empty())return true;
        else return false;
    }
};

NO.17電話號碼的字母組合

class Solution {
public:
    map<char,string> mp = {{'2',"abc"},{'3',"def"},{'4',"ghi"},{'5',"jkl"},  {'6',"mno"},{'7',"pqrs"},{'8',"tuv"},{'9',"wxyz"}};
    vector<string> res;
    string cur;
    vector<string> letterCombinations(string digits) {
   
        if(digits=="")return res;
        DFS(digits);
        return res;
        
    }
    
    void DFS(string digit){
        if(digit=="")res.push_back(cur);
        else{
            char num = digit[0];
            string letter = mp[num];
            for(int i=0;i<letter.size();i++){
                cur.push_back(letter[i]);
                DFS(digit.substr(1));
                cur.pop_back();
            }
        }
    }
    
    
    
};

NO26.刪除排序數組中的重複項

①兩個指針,從前往後判斷,如果後一個與當前相同,後指針不斷往後移;遇到不同值時,將後指針的值覆蓋前指針的下一個值,前指正++

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if(nums.size()<2)return nums.size();
        int j=0;
        for(int i=1;i<nums.size();i++){
            if(nums[j]!=nums[i]){
                nums[++j]=nums[i];
            }
        }
        return ++j;
    }
};

NO.27移除元素

Question:爲什麼vector的remove用不了?

暫時使用雙指針。

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int j=0;
        for(int i=0;i<nums.size();i++){
            if(nums[i]!=val){
                nums[j]=nums[i];
                j++;
            }
        }
        return j;
    }
};

NO28.實現strStr()

思路:主要用到了string的find函數,如果找不到,函數會返回:string::npos

class Solution {
public:
    int strStr(string haystack, string needle) {
        if(needle=="")return 0;
        if(haystack=="" || haystack.size()<needle.size())return -1;
        int res = haystack.find(needle);
        if(res==string::npos)return -1;
        else return res;
    }
};

NO35.搜索插入位置

沒有用二分查找,直接一遍迭代過去了。

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int n= nums.size();
        for(int i=0;i<n;i++){
            if(nums[i]>=target)return i;
        }
        return n;
    }
    
};

NO53.求最大子序列和

①:分治法

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        if(nums.size()==0)return 0;
        return func(nums,0,nums.size()-1);
    }
    int func(vector<int>&nums , int l, int r){
        if(l==r)return nums[l];
        int mid = (l+r)/2;
        int left = func(nums,l,mid);
        int right = func(nums,mid+1,r);
        int sum=0;
        int tr=0x80000000,tl=0x80000000;
        for(int i=mid+1;i<=r;i++){
            sum+=nums[i];
            if(sum>tr)tr=sum;
        }
        
        sum=0;
        for(int i=mid;i>=l;i--){
            sum+=nums[i];
            if(sum>tl)tl=sum;
        }
        
        sum = tl+tr;
        int m = max(left,right);
        return max(m,sum);
        
    }
};

NO55.跳躍遊戲

①先用了遞歸,試了幾個測試用例都通過了,但是超時orz

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int n = nums.size();
        if(n==1)return true;
        if(digui(nums,0,n-1))return true;
        return false;
    }
    bool digui(vector<int>& nums,int curPosition,int n){
        if(curPosition==n)return true;
        for(int i=1;i<=nums[curPosition];i++){
            if(digui(nums,curPosition+i,n))return true;
            else continue;
        }
        return false;
    }
};

②看了評論的思路:

從後往前找,如果發現nums[i]=0,則從i往前找,是否有nums[j]>i-j,有則可以跳過這個0,無則return false。

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int n = nums.size();
        if(n==1)return true;
        for(int i=n-2;i>=0;i--){
            if(nums[i]==0){
                int flag = 0;
                for(int j=i-1;j>=0;j--){
                    if(nums[j]>i-j){
                        i=j;
                        flag=1;
                        break;
                    }
                }
                if(flag==0)return false;
            }
        }
        return true;
    }

};

NO66.加一

注意vector的插入和刪除方法。

class Solution {
public:
    vector<int> plusOne(vector<int>& digits) {
        int n = digits.size();
        digits[n-1]+=1;
        int d=0;
        for(int i=n-1;i>=0;i--){
            int temp = digits[i]+d;
            if(temp>=10){
                digits[i]=temp-10;
                d=1;
            }else{
                digits[i]=temp;
                d=0;
            }
        }
        if(d==1)digits.insert(digits.begin(),1);
        return digits;
    }
};

NO83.刪除排序鏈表中的重複元素

class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if(head==NULL) return head;
        ListNode * last = head;
        ListNode * p = head->next;
        while(p){
            if(p->val==last->val){
                p=p->next;
                last->next = p;
            }else{
                p=p->next;
                last = last->next;
            }
        }
        return head;
        
    }
};

NO94.二叉樹的中序遍歷

Note:vector的插入,push_back(element);

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> ans;
        travers(root,ans);
        return ans;
        
    }
    
    void travers(TreeNode* t,vector<int> & a){
        if(t==NULL)return;
        travers(t->left,a);
        a.push_back(t->val);
        travers(t->right,a);
    }
};

NO98.驗證二叉搜索樹

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int flag = 0;
    bool isValidBST(TreeNode* root) {
        if(root==NULL)return true;
        int min = getMin(root);
        min = (min==0x80000000)?min:(min-1);
        return judge(root,min);
    }
    
    int getMin(TreeNode* root){
        if(root->left==NULL)return root->val;
        return getMin(root->left);
    }
    
    bool judge(TreeNode* root,int & max){
        if(root==NULL)return true;
        bool left = judge(root->left,max);
        if(left){
            if(flag==0){
                flag=1;
            }else if(root->val<=max){
                return false;
            } 
            max = root->val;
            return judge(root->right,max);
        }else return false;
        
    }
};

NO100.相同的樹

思路:遞歸判斷

class Solution {
public:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if(p==NULL && q==NULL)return true;
        if(p==NULL || q==NULL)return false;
        if(p->val == q->val){
            bool left = isSameTree(p->left,q->left);
            bool right = isSameTree(p->right,q->right);
            return left&right;
        }else return false;
    }
};

NO101.對稱二叉樹

思路:同上,遞歸判斷

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if(root==NULL)return true;
        return iss(root->left,root->right);
    }
    bool iss(TreeNode* l,TreeNode* r){
        if(l==NULL && r==NULL)return true;
        if(l==NULL || r==NULL)return false;
        if(l->val != r->val) return false;
        bool s1 = iss(l->left,r->right);
        bool s2 = iss(l->right,r->left);
        return s1 & s2;
        
    }
};

NO104.二叉樹的最大深度

Note:遞歸

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(root==NULL)return 0;
        else {
            int left =  maxDepth(root->left)+1;
            int right = maxDepth(root->right)+1;
            return max(left,right);
        }   
    }
};

NO108.將有序數組轉換爲二叉樹

思路:從中間開始二分

class Solution {
public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        return fun(nums,0,nums.size()-1);
    }
    TreeNode* fun(vector<int> & nums,int l , int r){
        if(l>r)return NULL;
        int mid=(l+r)/2;
        TreeNode * root = new TreeNode(nums[mid]);
        root->left = fun(nums,l,mid-1);
        root->right = fun(nums,mid+1,r);
        return root;
        
    }
};

NO111.二叉樹的最小深度

class Solution {
public:
    int minDepth(TreeNode* root) {
        if(root==NULL){
            return 0;
        }
        int left = minDepth(root->left);
        int right = minDepth(root->right);
        int ans;
        if(left&&right)ans = 1+min(left,right);
        else ans = 1+left+right;
        return ans;
    }
};

NO169.求衆數

思路:①排序後返回中間的位置即可。②注意sort函數用法

ps:沒有懂那個位運算法

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        return nums[nums.size()/2];
    }
};

NO136.只出現一次的數字

思想:a^a=0,0^a=a,所以因爲其他數都出現兩次,所以其他的結果都爲0,留下的一個爲只出現一次。

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int res  = 0;
        for(int i=0;i<nums.size();i++){
            res = res^nums[i];
        }
        return res;
    }
};

NO841.鑰匙和房間

思路:使用dfs算法

class Solution {
public:
    int a[1000];
    bool canVisitAllRooms(vector<vector<int>>& rooms) {
        int n = rooms.size();
        memset(a,0,n*sizeof(int));
        dfs(0,rooms);
        for(int i=0;i<n;i++){
            if(a[i]==0)return false;
        }
        return true;
    }
    void dfs(int x,vector<vector<int>> & rooms){
        a[x]++;
        vector<int> keys = rooms[x];
        int n=keys.size();
        int key=0;
        for(int i=0;i<n;i++){
            key = keys[i];
            if(a[key]==0){
                dfs(key,rooms);
            }
        }
        
    }
};

NO938.二叉搜索樹的範圍和

思路:①首先注意到二叉搜索樹的興致,左和右之間的所有節點即爲L<=X<=R

②遞歸,遍歷每個節點的左子樹和右子樹,若爲空節點,返回0。

return rangeSumBST(root->left,L,R)+rangeSumBST(root->right,L,R);

class Solution {
public:
    int rangeSumBST(TreeNode* root, int L, int R) {
        if(root==NULL)return 0;
        int val = root->val;
        if(val>=L && val<= R)return rangeSumBST(root->left,L,R)+rangeSumBST(root->right,L,R)+val;
        else return rangeSumBST(root->left,L,R)+rangeSumBST(root->right,L,R);
    }
};

NO1137.第n個泰波那契書

思路:遞歸return f(n-3)+f(n-2)+f(n-1);

NOTE:純用遞歸會超時,所以建立一個數組,每算得一個f(n)可以存入數組中,這樣後續可直接調用數組。

class Solution {
public:
    int A[40]={0,1,1};
    int tribonacci(int n) {
        if(n==0)return 0;
        else if(A[n]) return A[n];
        else{
            int  ans = (tribonacci(n-3)+tribonacci(n-2)+tribonacci(n-1));
            A[n]=ans;
            return ans;
        };
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章