Rrui的Leetcode算法刷题笔记(四)

151. Reverse Words in a String

class Solution {
public:
    void reverseWords(string &s) {
        
        if(s.empty())
            return ;
        
        string k,p;
        
        for(int i=0;i<s.size();i++)
        {
            if(s[i]==' ')
            {
                if(!p.empty())
                {
                    k=" "+p+k;
                    p.clear();
                }
                continue;   
            }
            p+=s[i];
        }
        if(!p.empty())
            k=p+k;
        else if(!k.empty())
            k=k.substr(1);
        s=k;
    }
};

注:中等题,这题有病,还不让测试的。faster than 31.57%。

152. Maximum Product Subarray


class Solution {
public:
    int maxProduct(vector<int>& nums) {
        int n=nums.size();
        vector<int> maxnum(n,0),minnum(n,0);
        int maxres=INT_MIN;
        for(int i=0;i<n;i++){
            if(i==0){
                maxnum[i]=nums[i];
                minnum[i]=nums[i];
            }
            else{
                maxnum[i]=max(maxnum[i-1]*nums[i],max(minnum[i-1]*nums[i],nums[i]));
                minnum[i]=min(maxnum[i-1]*nums[i],min(minnum[i-1]*nums[i],nums[i]));
            }
            maxres=max(maxres,maxnum[i]);
        }
        return maxres;
    }
};

https://www.cnblogs.com/ganganloveu/p/4089925.html

https://www.cnblogs.com/bakari/p/4007368.html

注:中等题,典型的动态规划,不会。faster than XX%。
153. Find Minimum in Rotated Sorted Array

class Solution {
public:
    int findMin(vector<int>& nums) {
        
        int low=0,high=nums.size()-1;
        while(high>=low)
        {
            int mid=(high+low)/2;
            if(nums[mid]>nums[low])
            {
                if(nums[low]>nums[high])
                    low=mid+1;
                else high=mid-1;
            }
            else
            {
                if(mid-1>=low&&nums[mid]<nums[mid-1])
                    return nums[mid];
                else  if(mid-1>=low&&nums[mid]>nums[mid-1])
                    high=mid-1;    
                else if(mid+1<=high&&nums[mid]>nums[mid+1])
                    low=mid+1;
                else return nums[mid];
            }
        }
        return nums[low]; 
    }
};

注:中等题,与第33题类似,主要是找有序区间。faster than 48.15%。

154. Find Minimum in Rotated Sorted Array II

class Solution {
public:
    int findMin(vector<int>& nums) {
        
        int low=0,high=nums.size()-1;
        while(high>=low)
        {
            int mid=(high+low)/2;
            if(nums[mid]==nums[low]&&mid!=low)
                low++;
            else if(nums[mid]>nums[low])
            {
                if(nums[low]>=nums[high])
                    low=mid+1;
                else high=mid-1;
            }
            else
            {
                if(mid-1>=low&&nums[mid]<nums[mid-1])
                    return nums[mid];
                else  if(mid-1>=low&&nums[mid]>=nums[mid-1])
                    high=mid-1;    
                else if(mid+1<=high&&nums[mid]>=nums[mid+1])
                    low=mid+1;
                else return nums[mid];
            }
        }
        return nums[low]; 
    }
};

注:困难题,上一题的加强版,加个判断条件,以前的判断条件都换成等号就行了。faster than 99.05%。

155. Min Stack

class MinStack {
public:
    /** initialize your data structure here. */
            
    vector<int> a;
    int min=INT_MAX;
    
    MinStack(){}
    
    void push(int x) {        
        a.push_back(x);  
    }
    
    void pop() {
        a.pop_back();       
    }
    
    int top() {
        return a[a.size()-1];       
    }
    
    int getMin() {
    
        int k=min;
        for(int i=0;i<a.size();i++)
            if(a[i]<k)
                k=a[i];
        
        return k;        
    }

};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack obj = new MinStack();
 * obj.push(x);
 * obj.pop();
 * int param_3 = obj.top();
 * int param_4 = obj.getMin();
 */

注:简单题,懒得说了。faster than 5.29%。

160. Intersection of Two Linked Lists

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        
        ListNode *p=headA,*q=headB;
        int n=1,m=1;
        
        if(!p||!q)
            return NULL;
        
        while(p->next)
        {
            p=p->next;
            n++;
        }
        
        while(q->next)
        {
            q=q->next;
            m++;
        }  
        
        if(q!=p)
            return NULL;
        
        while(--n&&--m)
        {
            ListNode *c=headA,*d=headB;    
            
            int a=n-1,b=m-1;
            
            while(a--)
                c=c->next;

            while(b--)
                d=d->next;         
            
            if(c!=d)
                return c->next;
        }
        
        if(!n)
            return headA;
        else return headB;      
    }
};

注:简单题,纯暴力解法,优解与前面第141题判断是否有环很相似。faster than 46.84%。

162. Find Peak Element

class Solution {
public:
    int findPeakElement(vector<int>& nums) {
        
        int i = 0;
        int j = nums.size() - 1;
        while(i < j)
        {
            int temp = (i + j) / 2;
            if(nums[temp] > nums[temp + 1])
            {
                j = temp;
            }
            else
            {
                i = temp + 1;
            }
        }
        return i;
    }
};


http://courses.csail.mit.edu/6.006/spring11/lectures/lec02.pdf

注:中等题,纯暴力解法,其实要求的复杂度一看就是2分法,2分法思路链接如上,非常聪明。faster than 16.51%。

164. Maximum Gap

class Solution {
public:
    int maximumGap(vector<int>& nums) {
        
        if(nums.size()<=1)
            return 0;
        
        sort(nums.begin(),nums.end());
        
        int dif=0,max=INT_MIN;
        for(int i=1;i<nums.size();i++)
        {
            dif=nums[i]-nums[i-1];
            if(dif>max)
                max=dif;
        }
        return max;
    }
};

注:困难题,sort一下就行了,线性时间的不会。faster than 99.05%。

165. Compare Version Numbers

class Solution {
public:
    int compareVersion(string version1, string version2) {
        
        int i=0,j=0;
        while(i<version1.size()||j<version2.size())
        {
            int a=0,b=0;
            
            while(i<version1.size()&&version1[i]!='.')
                a=10*a+version1[i++]-'0';

            while(j<version2.size()&&version2[j]!='.')
                b=10*b+version2[j++]-'0';            
            
            if(a<b)
                return -1;
            else if(a>b)
                return 1;
            i++;
            j++;
        }
        return 0; 
    }
};

注:中等题,没啥难度。faster than 100%。

166. Fraction to Recurring Decimal

class Solution {
public:
    string fractionToDecimal(int numerator, int denominator) {
        long long t = numerator, d = denominator;
        map<long long, int> A;
        string ans;
        if (t*d < 0) ans = "-";
        t = abs(t), d = abs(d);
        ans += to_string(t / d);
        t %= d;
        if (!t) return ans;
        ans += '.';
        while (t) {
            if (A.count(t)) {
                ans.insert(A[t], "("), ans.push_back(')');
                return ans;
            }
            A[t] = ans.size(), ans += '0' + t * 10 / d;
            t = t * 10 % d;
        }
        return ans;
    }
};

注:中等题,考察循环小数判定,出现重复的数字就是循环小数了,利用哈希表。faster than XX%。

167. Two Sum II - Input array is sorted

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        
        int left=0,right=numbers.size()-1;
        
        while(right>left)
        {
            if(numbers[left]+numbers[right]>target)
                right--;
            else if(numbers[left]+numbers[right]<target)
                left++;
            else return {left+1,right+1};
        }
        return {};
    }
};

注:简单题,既然已经是升序排列的数组,完全可以双指针法求解。faster than 99.06%。

168. Excel Sheet Column Title

class Solution {
public:
    string convertToTitle(int n) {
        
        string s;
        
        if((n-1)/26>=1)
        {
            int k=(n-1)/26;
            s+=convertToTitle(k);  
        }
        s=s+char('A'+(n-1)%26);    

        return s;
    }
};

注:简单题,递归求解就好了,唯一需要注意的问题就是字母是从1开始计算的。faster than 100%。

169. Majority Element

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        
        map<int,int> a;
        
        for(int i=0;i<nums.size();i++)
        {
            if(a.find(nums[i])==a.end())
                a[nums[i]]=1;
            else ++a[nums[i]];
        }
        
        int min=0,p;
            
        for(map<int, int>::iterator i=a.begin();i!=a.end();i++)   
        {
            if(i->second>min)
            {
                min=i->second;
                p=i->first;
            }
        }
        return p;
    }
};

注:简单题,用的最直接的map计数方法,最优解是一次遍历计数。faster than 13.41%。

171. Excel Sheet Column Number

class Solution {
public:
    int titleToNumber(string s) {
      
        int sum=0;
        
        for(int i=0;i<s.size();i++)
            sum=sum*26+s[i]-'A'+1;

        return sum;
    }
};

注:简单题,没啥好说的。faster than 98.41%。

172. Factorial Trailing Zeroes

class Solution {
public:
    int trailingZeroes(int n) {
        int count = 0;
        while (n > 1)
            count += (n /= 5);
        return count;
    }
};

注:简单题,找规律。faster thanXX%。

173. Binary Search Tree Iterator

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class BSTIterator {
public:
    
    vector<int> a;
    int p=0;
    BSTIterator(TreeNode* root) {
        
        if(root)
        {
           stack<TreeNode*> s;
            TreeNode* p=root;
            while(p||!s.empty())
            {
                while(p)
                {
                    s.push(p);
                    p=p->left;
                }
                p=s.top();
                s.pop();
                a.push_back(p->val);            
                p=p->right;
            }
        }
    }
    
    /** @return the next smallest number */
    int next() {
        return a[p++];
    }
    
    /** @return whether we have a next smallest number */
    bool hasNext() {
        return p<a.size();
    }
};

/**
 * Your BSTIterator object will be instantiated and called as such:
 * BSTIterator* obj = new BSTIterator(root);
 * int param_1 = obj->next();
 * bool param_2 = obj->hasNext();
 */

注:中等题,其实就是二叉树中序遍历。faster than 1.2%。

174. Dungeon Game

注:困难题,。faster than XX%。

179. Largest Number

自己debug版:

class Solution {
private:
    static bool key(int a,int b)
    {
        string p=to_string(a);
        string q=to_string(b);
        int i=0,j=0;
        while(i<p.size()||j<q.size())
        {
            if(i>=p.size())
            {
                while(j<q.size()&&(q[0]==q[j]))
                    j++;
                if(j>=q.size()||q[0]==q[j])
                    return true;
                return q[0]>q[j];
            }
            else if(j>=q.size())
                return p[0]<p[i];            
            else if(p[i]!=q[j])
                return p[i]>q[j];
            i++;
            j++;
        }
        return false; 
    }
public:

    string largestNumber(vector<int>& nums) {
        
        sort(nums.begin(),nums.end(),key);
        string s;
        for(int i=0;i<nums.size();i++)
            s+=to_string(nums[i]);
        if(s[0]=='0')
        {
            s.clear();
            s+='0';        
        }
        return s;
    }
};

别人AC版:

class Solution {
public:
    string largestNumber(vector<int>& nums) {
        vector<string> numStr;
        for(int num: nums)
            numStr.push_back(to_string(num));
        sort(numStr.begin(), numStr.end(), cmp);
        if(numStr.size() && numStr[0] == "0") return "0";
        string s = "";
        for(string num: numStr)
            s += num;
        return s;
    }
    static bool cmp(string i, string j){
        return i + j > j + i;
    }
};

注:中等题,重点是判断两数谁打谁小那,我写的太麻烦了,自己都绕进去了。faster than XX%。

187. Repeated DNA Sequences

class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) {
        
        unordered_map<string,int> a;
        vector<string> b;
        if(s.size()<10)
            return b;
        for(int i=0;i<=s.size()-10;i++)
        {
            string p=s.substr(i,10);
            if(a.find(p)==a.end())
                a[p]=1;
            else if(a[p]==1)
            {
                b.push_back(p);
                a[p]++;
            }
        }
        return b;
    }
};

注:中等题,哈希表的应用。faster than 24.31%。

188. Best Time to Buy and Sell Stock IV

注:困难题,。faster than XX%。

189. Rotate Array

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        
        int size=nums.size();
        int n=k%size;
        
        for(int i=0;i<size-n;i++)
        {
            int a=nums[0];
            nums.erase(nums.begin());
            nums.push_back(a);
        }
    }
};

注:简单题,没意思。faster than 15.95%。

190. Reverse Bits

class Solution {
public:
    uint32_t reverseBits(uint32_t n) {
        
        uint32_t k;
        int a=32;
        while(a--)
        {
            k=k*2+n%2;
            n/=2;
        }
        return k;
    }
};

注:简单题,2进制操作。faster than 87.18%。

191. Number of 1 Bits

class Solution {
public:
    int hammingWeight(uint32_t n) {
        
        int k=0;
        
        while(n!=0)
        {
            if(n%2)
                k++;
            n/=2;            
        }
        return k;
    }
};

注:简单题,二进制找1。faster than 75.60%。

198. House Robber

记忆化搜索:

class Solution {
public:
    int rob(vector<int>& nums) {
        
        vector<int> a(nums.size(),-1);
        
        return digui(nums,a,0);
    }
    
    int digui(vector<int>& nums,vector<int>& a,int k)
    {
        if(k>=nums.size())
            return 0;        
        
        if(a[k]!=-1)
            return a[k];
        
        a[k]=max(digui(nums,a,k+2)+nums[k],digui(nums,a,k+1));
        
        return a[k];
    }
};

动态规划:

class Solution {
public:
    int rob(vector<int>& nums) {
        
        vector<int> a(nums.size()+1,0);
        
        for(int i=nums.size()-1;i>=0;i--)
        {
            if(i==nums.size()-1)
                a[i]=nums[i];
            else
                a[i]=max(a[i+1],nums[i]+a[i+2]);
        }
        return a[0];
    }
};

注:简单题,典型的动态规划。faster than 35.93%。

199. Binary Tree Right Side View

/**
 * 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> rightSideView(TreeNode* root) {
        
        vector<int> a;
        queue<TreeNode*> p;
        
        if(!root)
            return a;
        p.push(root);
        
        while(!p.empty())
        {
            int size=p.size();
            TreeNode* q;
            while(size--)
            {
                q=p.front();
                if(q->left)
                    p.push(q->left);
                if(q->right)
                    p.push(q->right);
                p.pop();
            }
            a.push_back(q->val);
        }
        return a;
    }
};

注:中等题,其实就是二叉树层序遍历只记录每一层的最后一个。faster than 47.86%。

200. Number of Islands

class Solution {
public:
    int numIslands(vector<vector<char>>& grid) {
        
        if(grid.size()==0||grid[0].size()==0)
            return 0;
        vector<vector<int>> a(grid.size(),vector<int>(grid[0].size(),0));
        int p=0;
        for(int i=0;i<grid.size();i++)
            for(int j=0;j<grid[0].size();j++) 
                if(grid[i][j]=='1')
                {
                    if(a[i][j]==1)
                        continue;
                    else
                    {
                        digui(a,grid,i,j);
                        p++;
                    }
                }
        return p;
    }
 
    void digui(vector<vector<int>>& a,vector<vector<char>>& grid,int i,int j)
    {
        a[i][j]=1;
        
        if(i-1>=0&&grid[i-1][j]=='1'&&a[i-1][j]==0)
            digui(a,grid,i-1,j);
        if(j-1>=0&&grid[i][j-1]=='1'&&a[i][j-1]==0)
            digui(a,grid,i,j-1); 
        if(j+1<grid[0].size()&&grid[i][j+1]=='1'&&a[i][j+1]==0)
            digui(a,grid,i,j+1);      
        if(i+1<grid.size()&&grid[i+1][j]=='1'&&a[i+1][j]==0)
            digui(a,grid,i+1,j);
    }
};

注:中等题,我用的深度优先搜索,与79题想法相同,代码就是抄过来修改的。faster than 55.82%

201. Bitwise AND of Numbers Range

class Solution {
public:
    int rangeBitwiseAnd(int m, int n) {
        int i = 0;
        while (m != n) {
            m >>= 1;
            n >>= 1;
            ++i;
        }
        return (m << i);
    }
};

注:中等题,不会。faster than XX%。

202. Happy Number

class Solution {
public:
    bool isHappy(int n) {
        
        int p=0;
        
        while(1)
        {
            int a=n,k=0;
            while(a)
            {
                k+=pow(a%10,2);
                a/=10;
            }
            if(k==1)
                return true;
            n=k;
            p++;
            if(p>10000)
                return false;
        }     
    }
};

注:简单题,他们找规律说如果不得1的话会得到循环,我没找到这种规律,直接就用的风骚法。。faster than 0.99%。

203. Remove Linked List Elements

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        
        ListNode *q=new ListNode(0);
        ListNode* p=q;
        p->next=head;
        
        while(p->next)
        {
            if(p->next->val==val)
            {
                p->next=p->next->next;
                continue;
            }
            p=p->next;
        }
        
        return q->next;
    }
};

注:简单题,没啥说的。faster than 31.52%。

204. Count Primes

class Solution {
public:
    int countPrimes(int n) {
        
        int sum=0;
        vector<int> a(n,0);
        
        for(int i=2;i<n;i++)
        {
            if(!a[i])
            {
                sum++;
                for(int j=2;j*i<n;j++)
                    a[j*i]=1;
            }
        }
        return sum;
    }
};

注:简单题,这题用哈希表要超时,只能用vector,j从2开始取值。faster than 54.51%。

205. Isomorphic Strings

class Solution {
public:
    bool isIsomorphic(string s, string t) {
        
        if(s.size()!=t.size())
            return false;
        unordered_map<char,char> a,b;
        
        for(int i=0;i<s.size();i++)
        {
            if(a.find(s[i])==a.end())
            {
                a[s[i]]=t[i];                
            }
            else if(a[s[i]]!=t[i])
                return false;
            
            if(b.find(t[i])==b.end())
            {
                b[t[i]]=s[i];                
            }
            else if(b[t[i]]!=s[i])
                return false;            
        }
        return true;
    }
};

注:简单题,用两个map杜绝一个字母对应两个索引的情况。faster than 30.70%。

206. Reverse Linked List

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        
        ListNode* p=NULL;
        ListNode* q=head;
        if(!head)
            return NULL;
        ListNode* r=head->next;
        
        while(r)
        {
            q->next=p;
            p=q;
            q=r;
            r=r->next;
            if(!r)
                q->next=p;
        }
        return q;
    }
};

注:简单题,经典的反转链表,不会编的话在纸上画个链表就会了。faster than 47.99%。

207. Course Schedule

注:中等题,本题其实有个无比风骚的代码。正常的是用map做的。faster than 37.46%。

208. Implement Trie (Prefix Tree)

注:中等题,本题其实有个无比风骚的代码。正常的是用map做的。faster than 37.46%。

209. Minimum Size Subarray Sum

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        
        int sum=0,left=0,right=0,min1=INT_MAX;
        
        while(right<nums.size())
        {
            sum+=nums[right++];
            while(sum>=s)
            {
                min1=min(min1,right-left);
                sum-=nums[left++];
            }
        }
        return min1==INT_MAX?0:min1;
    }
};

注:中等题,双指针法解决。faster than 49.08%。

210. Course Schedule II

注:中等题,双指针法解决。faster than 49.08%。

211. Add and Search Word - Data structure design

注:中等题,本题其实有个无比风骚的代码。正常的是用map做的。faster than 37.46%。

212. Word Search II

注:中等题,本题其实有个无比风骚的代码。正常的是用map做的。faster than 37.46%。

213. House Robber II

class Solution {
public:
    int rob(vector<int>& nums) {
        
        vector<int> a(nums.size(),-1);
        vector<int> b(nums.size(),-1);
        if(nums.size()==1)
            return nums[0];
            
        return max(digui(nums,a,0,nums.size()-1),digui(nums,b,1,nums.size()));
    }
    
    int digui(vector<int>& nums,vector<int>& a,int k,int p)
    {
        if(k>=p)
            return 0;        
        
        if(a[k]!=-1)
            return a[k];
        
        a[k]=max(digui(nums,a,k+2,p)+nums[k],digui(nums,a,k+1,p));
        
        return a[k];
    }
};

注:中等题,本题相比于198题多出了头尾的限制条件,需要在主函数中进行限制,要头不要尾或要尾不要头,这点我没想到。faster than 40.67%。

214. Shortest Palindrome

注:中等题,本题其实有个无比风骚的代码。正常的是用map做的。faster than 37.46%。

215. Kth Largest Element in an Array

风骚代码:

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

正常代码:

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        
        map<int,int> a;
        
        for(int i=0;i<nums.size();i++)
            a[nums[i]]++;
        
        int j=0;
        for(map<int,int>::iterator i=a.begin();i!=a.end();i++)
        {
            j+=i->second;
            if(nums.size()-j<=k-1)
                return i->first;
        }
    }
};

注:中等题,本题其实有个无比风骚的代码。正常的是用map做的。faster than 37.46%。

216. Combination Sum III

class Solution {
public:
    vector<vector<int>> combinationSum3(int k, int n) {
        
        vector<vector<int>> a;
        vector<int> b;
        digui(a,b,k,n,0,1);
        return a;
    }
    void digui(vector<vector<int>>& a,vector<int>& b,int k, int n,int p,int q)
    {
        if(b.size()==k)
        {
            if(p==n)
                a.push_back(b);
            return;
        }
        
        for(int i=q;i<=9;i++)
        {
            b.push_back(i);
            digui(a,b,k,n,p+i,i+1);
            b.pop_back();
        }
    }
};

注:中等题,典型的回溯法。faster than 100%。

Rrui的Leetcode算法刷题笔记(五)链接如下:

https://blog.csdn.net/Rrui7739/article/details/83540288

猜你喜欢

转载自blog.csdn.net/Rrui7739/article/details/83272519