Leetcode算法刷题笔记(三)

101. Symmetric Tree

/**
 * 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:
    bool isSymmetric(TreeNode* root) {
        
        if(!root)
            return true;
        return digui(root->left,root->right);
    }
    
    bool digui(TreeNode* a,TreeNode* b)
    {
        if(!a&&!b)
            return true;
        if(!a||!b)
            return false;
        if(a->val!=b->val)
            return false;
        return digui(a->left,b->right)&&digui(a->right,b->left);
    }
};

注:简单题,左右子树递归看看相不相等就好了,没啥难度。faster than 98.92% 。

102. Binary Tree Level Order Traversal

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

注:中等题,每一层用队列就好了,用k记录每层的节点数,没难度。faster than 98.76% 。

103. Binary Tree Zigzag Level Order Traversal

/**
 * 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<vector<int>> zigzagLevelOrder(TreeNode* root) {
        
        queue<TreeNode*> q;
        stack<TreeNode*> s;
        vector<int> m;
        vector<vector<int>> n;
        int size;
        int p=0;
        if(!root)
            return n;
        
        q.push(root);
        
        while(!q.empty())
        {
            TreeNode*a;
            
            size=q.size();
            while(size--)
            {
                a=q.front();
                if(a->left)
                    q.push(a->left);
                if(a->right)
                    q.push(a->right);
                m.push_back(a->val);
                q.pop();
            }
            p++;
            if(p%2==0)
                reverse(m.begin(),m.end());
            n.push_back(m);
            m.clear();
        }
        
        
        return n;
    }
};

注:中等题,102题的基础上每隔一行反转一下就好了。faster than 100.00% 。

104. Maximum Depth of Binary Tree

/**
 * 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) {
        
        return digui(root,1);
    }
    
    int digui(TreeNode* root,int k)
    {
        if(!root)
            return k-1;
        
        return max(digui(root->left,k+1),digui(root->right,k+1));
    }
};

注:简单题,直接就递归求解吧,没啥难度。faster than 28.61% 。

105. Construct Binary Tree from Preorder and Inorder Traversal

/**
 * 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:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        
        if(preorder.size()==0)
            return NULL;
        
        vector<int> a{0};
        return digui(preorder,inorder,a,0);
    }
    
    TreeNode* digui(const vector<int> &preorder,const vector<int> &inorder,vector<int> &a,int j) 
    {
        TreeNode* root=new TreeNode(preorder[a[0]]);
        
        int p=0;
        while(inorder[p]!=preorder[a[0]])
            p++;
        
        a[0]++;

        if(p==0)
            root->left=NULL;
        else
        {
            vector<int> left(inorder.begin(),inorder.begin()+p);
            root->left=digui(preorder,left,a,0);                
        }

        if(p+1==inorder.size())
            root->right=NULL;
        else
        {
            vector<int> right(inorder.begin()+p+1,inorder.begin()+inorder.size());  
            root->right=digui(preorder,right,a,0);                
        }
        return root;
    }
};

注:中等题,根据中序遍历和前序遍历的特点来找根节点,找到了以后就左右子树再递归,思路跟别人的都一样,我这么慢的原因估计是额外声明了两个vector。faster than 15.63% 。

106. Construct Binary Tree from Inorder and Postorder Traversal

/**
 * 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:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        
        if(inorder.size()==0)
            return NULL;
        
        vector<int> a{postorder.size()-1};
        return digui(postorder,inorder,a,0);
    }
    
    TreeNode* digui(const vector<int> &postorder,const vector<int> &inorder,vector<int> &a,int j) 
    {
        TreeNode* root=new TreeNode(postorder[a[0]]);
        
        int p=0;
        while(inorder[p]!=postorder[a[0]])
            p++;
        
        a[0]--;

        if(p+1==inorder.size())
            root->right=NULL;
        else
        {
            vector<int> right(inorder.begin()+p+1,inorder.begin()+inorder.size());  
            root->right=digui(postorder,right,a,0);                
        }
        
        if(p==0)
            root->left=NULL;
        else
        {
            vector<int> left(inorder.begin(),inorder.begin()+p);
            root->left=digui(postorder,left,a,0);                
        }
        return root;
    }
};

注:中等题,思路同105题,从后往前遍历preorder,先右后左遍历子节点。faster than 12.95% 。

107. Binary Tree Level Order Traversal II

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

注:简单题,在102题层序遍历的基础上加个栈就好了,没啥难度。faster than 98.83% 。

108. Convert Sorted Array to Binary Search Tree

/**
 * 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:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        
        return digui(nums,0,nums.size()-1);
    }
    
    TreeNode* digui(vector<int>& nums,int p,int q)
    {
        if(p>q)
            return NULL;
        
        int mid=(p+q)/2;
        
        TreeNode* root=new TreeNode(nums[mid]);
        
        root->left=digui(nums,p,mid-1);
        root->right=digui(nums,mid+1,q);
        
        return root;
    }
};

注:简单题,二分递归找根节点就好。faster than 42.55% 。

109. Convert Sorted List to Binary Search Tree

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode *sortedListToBST(ListNode *head) {
        if (!head) return NULL;
        if (!head->next) return new TreeNode(head->val);
        ListNode *slow = head;
        ListNode *fast = head;
        ListNode *last = slow;
        while (fast->next && fast->next->next) {
            last = slow;
            slow = slow->next;
            fast = fast->next->next;
        }
        fast = slow->next;
        last->next = NULL;
        TreeNode *cur = new TreeNode(slow->val);
        if (head != slow) cur->left = sortedListToBST(head);
        cur->right = sortedListToBST(fast);
        return cur;
    }
};

注:中等题,我的思路跟他的一模一样,但是自己在快慢指针那给自己绕进去了从此不能自拔,快指针不能开始就定义为

head->next->next。。。faster than XX% 。

110. Balanced Binary Tree

/**
 * 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:
    bool isBalanced(TreeNode* root) {

        return digui(root,0)==INT_MAX?false:true;
    }
    
    int digui(TreeNode* root,int k)
    {
        if(!root)
            return k;
        
        int a=digui(root->left,k+1);
        int b=digui(root->right,k+1);
        if(abs(a-b)<=1)
            return max(a,b);
        else return INT_MAX;
    }
};

注:简单题,直接就递归求解吧,设置一个INT_MAX值代表不平衡,因为数高度绝对不可能为INT_MAX。faster than 27.26% 。

111. Minimum Depth of Binary Tree

/**
 * 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 minDepth(TreeNode* root) {
        
        return digui(root,1,false);
    }
    
    int digui(TreeNode* root,int k,bool a)
    {
        if(!root)
        {
            if(a)
                return INT_MAX;
            return k-1;
        }
        return min(digui(root->left,k+1,root->right),digui(root->right,k+1,root->left));
    }
};

注:简单题,直接就递归求解吧。faster than 100.00% 。

 

112. Path Sum

/**
 * 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:
    bool hasPathSum(TreeNode* root, int sum) {
        
        if(!root)
            return false;
                
        if(sum-root->val==0)
        {
            if(!root->left && !root->right)
                return true;
        }
        return hasPathSum(root->left, sum-root->val) || hasPathSum(root->right, sum-root->val);
    }
    
};

注:简单题,直接就递归求解吧,需要注意的是题目要求根节点到叶子结点。

Runtime: 16 ms, faster than 69.19% of C++ online submissions for Path Sum.

Memory Usage: 19.9 MB, less than 50.13% of C++ online submissions forPath Sum.

 

113. Path Sum II

/**
 * 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<vector<int>> pathSum(TreeNode* root, int sum) {
        
        vector<vector<int>> output;
        vector<int> cache;
        path(root, sum, output, cache);
        return output;
    }

    void path(TreeNode* root, int sum, vector<vector<int>>& output, vector<int> cache)
    {
        if(!root)
            return ;
        
        cache.push_back(root->val); 
        if(sum==root->val && !root->left && !root->right)
        {
            output.push_back(cache);
            return ;
        }
        
        
        path(root->left, sum-root->val, output, cache);
        path(root->right, sum-root->val, output, cache);        
    } 
};

注:中等题,思路同112 。

Runtime: 32 ms, faster than 22.76% of C++ online submissions for Path Sum II.

Memory Usage: 38.1 MB, less than 15.97% of C++ online submissions forPath Sum II.

 

114. Flatten Binary Tree to Linked List

/**
 * 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:
    void flatten(TreeNode* root) {
        
        digui(root,NULL);
    }
    
    TreeNode* digui(TreeNode* root,TreeNode* q)
    {
        if(!root)
            return NULL;
        
        TreeNode*p=NULL;
        if(root->left)
        {
            p=root->right;
            root->right=root->left;
            root->left=NULL;
        }
            root->right=digui(root->right,p);
        
        if(q)
        {
            TreeNode*a =root;
            while(a->right)
                a=a->right;
            
            a->right=digui(q,NULL);
        }
        return root;
        
    }       
};

注:中等题,还是递归问题,利用左子树替换右子树。faster than 15.78% 。

115. Distinct Subsequences

class Solution {
public:
	/*用删除的方法将串s变换到t,计算变换方法数*/
	int numDistinct(string s, string t) {
		if (s.empty() || t.empty())
			return 0;
		else if (s.length() < t.length())
			return 0;
		else
		{
			//动态规划
			int ls = s.length(), lt = t.length();
			/*保存由字符串s(0,i) --> t(0,j)的方法数*/
			vector<vector<int> > dp(ls + 1, vector<int>(lt + 1, 0));
			dp[0][0] = 1;
			for (int i = 0; i < ls; ++i)
			{
				/*s(0,i) 转换为 t(0)的方法数为1*/
				dp[i][0] = 1;
			}//for
			for (int i = 1; i <= ls; ++i)
			{
				for (int j = 1; j <= lt; ++j)
				{
					/*首先不管当前字符是否相同,为dp[i][j]赋初值*/
					dp[i][j] = dp[i - 1][j];
					if (s[i-1] == t[j-1])
					{
						/*如果s和t的当前字符相同,有两种选择保留或不保留*/
						dp[i][j] += dp[i - 1][j - 1];
					}//if
				}//for
			}//for
			return dp[ls][lt];
		}
	}	
};

https://blog.csdn.net/fly_yr/article/details/50408457

http://www.cnblogs.com/higerzhang/p/4133793.html

注:困难题,这题瞪眼一瞅就是动态规划,暴力解肯定超时,我也懒得写暴力解,然而尴尬的是还是不会。faster than XX% 。

116. Populating Next Right Pointers in Each Node/117. Populating Next Right Pointers in Each Node II

/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */
class Solution {
public:
    void connect(TreeLinkNode *root) {
        
        if(!root)
            return  ;      

        queue<TreeLinkNode *> a;
        TreeLinkNode *b;
        a.push(root);
        int k;
        
        while(!a.empty())
        {
            k=a.size()-1;
            
            while(k--)
            {
                b=a.front();
                if(a.front()->left)
                    a.push(a.front()->left); 
                if(a.front()->right)
                    a.push(a.front()->right); 
                a.pop();
                b->next=a.front();
            }                
            if(a.front()->left)
                a.push(a.front()->left); 
            if(a.front()->right)
                a.push(a.front()->right); 
            a.front()->next=NULL;
            a.pop();            
        }
    }
};

注:中等题,直接层序遍历就好了,没啥难度。faster than 35.56% /14.92%。

118. Pascal's Triangle

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        
        vector<vector<int>> a;
        vector<int> b,c;
        
        for(int i=0;i<numRows;i++)
        {
            if(i>0)
                b.push_back(1);
            for(int j=1;j<c.size();j++)
                b.push_back(c[j-1]+c[j]);
            b.push_back(1);
            a.push_back(b);
            c=b;
            b.clear();
        }
        return a;
    }
};

注:简单题,没啥难度。faster than 100.00% 。

119. Pascal's Triangle II

class Solution {
public:
    vector<int> getRow(int rowIndex) {

        vector<int> b,c;
        
        for(int i=0;i<=rowIndex;i++)
        {
            if(i>0)
                b.push_back(1);
            for(int j=1;j<c.size();j++)
                b.push_back(c[j-1]+c[j]);
            b.push_back(1);
            c=b;
            b.clear();
        }
        return c;
    }
};

注:简单题,118题把a删了就行了。faster than 100.00% 。

120. Triangle

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        
        int sum=INT_MAX;
        for(int i=0;i<triangle.size();i++)
        {
            if(i+1<triangle.size())
            {
                int k=INT_MAX;
                for(int j=0;j<triangle[i].size();j++)
                {
                    triangle[i+1][j]=min(k,triangle[i+1][j]+triangle[i][j]-(j==0?0 :triangle[i][j-1]));
                    triangle[i+1][j+1]+=triangle[i][j];
                    k=triangle[i+1][j+1];
                }
            }
            else
            {
                for(int j=0;j<triangle[i].size();j++)
                    sum=min(sum,triangle[i][j]);
            }
        }
        return sum==INT_MAX?0:sum;
    }
};

注:中等题,动态规划典型题,时间复杂度肯定是O(n*m),这题可以用O(n*m)空间复杂度或O(m)空间复杂度求解,我费劲扒拉弄了个O(1)的。faster than 21.14%。

 

121. Best Time to Buy and Sell Stock

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        
        if(prices.size()<2)
            return 0;
        
        int temp = 0, maximum = 0;
            
        for(int i=1;i<prices.size();i++)
        {
            temp += (prices[i]-prices[i-1]);
            maximum = max(temp, maximum);
            if(temp<=0)
                temp = 0;
        }
        return maximum;
    }
};

注:中等题,动态规划典型题,与连续子数组最大和的思想完全一致,不过本题内使用的是后一项减去前一项的差值

Runtime: 4 ms, faster than 98.79% of C++ online submissions for Best Time to Buy and Sell Stock.

Memory Usage: 9.4 MB, less than 80.84% of C++ online submissions forBest Time to Buy and Sell Stock.

 

122. Best Time to Buy and Sell Stock II

 

注:中等题,动态规划典型题,。前i天的最大收益 = max{前i-1天的最大收益,第i天的价格-前i-1天中的最小价格}。faster than XX%。

123. Best Time to Buy and Sell Stock III

 

注:困难题,动态规划典型题,。faster than XX%。

124. Binary Tree Maximum Path Sum

/**
 * 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 maxVal = INT_MIN;
	int maxPathSum(TreeNode* root) {
		if (root == NULL)
			return 0;
 
		maxSum(root);
		return maxVal;
	}
 
	/*递归函数*/
	int maxSum(TreeNode *root)
	{
		if (root == NULL)
			return 0;
 
		/*求以root为根的当前子树的最大路径和*/
		int curVal = root->val;
		int lmaxSum = maxSum(root->left), rmaxSum = maxSum(root->right);
		if (lmaxSum > 0)
			curVal += lmaxSum;
		if (rmaxSum > 0)
			curVal += rmaxSum;
 
		if (curVal > maxVal)
			maxVal = curVal;
 
		/*返回以当前root为根的子树的最大路径和*/
		return max(root->val, max(root->val + lmaxSum, root->val + rmaxSum));
	}
};

https://blog.csdn.net/fly_yr/article/details/50412751

注:困难题,这题名字真是他妈的吃了屎了,最长路径和,是最长路径下的最大和,他妈的,浪费老子半个点才把题读懂。faster than XX%。

125. Valid Palindrome

class Solution {
public:
    bool isPalindrome(string s) {
        
        int a=s.size()-1,q=0,p=0;

        for(int i=0;i<=a;i++)
        {
            while(s[i+q]>'z'||(s[i+q]>'Z'&&s[i+q]<'a')||(s[i+q]<'A'&&s[i+q]>'9')||(s[i+q]>31&&s[i+q]<'0'))
                q++;
            while(s[a-i-p]>'z'||(s[a-i-p]>'Z'&&s[a-i-p]<'a')||(s[a-i-p]<'A'&&s[a-i-p]>'9')||(s[a-i-p]>31&&s[a-i-p]<'0'))
                p++;
            if(i+q>a||a-i-p<0)
                break;
            if(s[i+q]!=s[a-i-p])
            {
                char b=s[i+q];
                if ((b>=65)&&(b<=90))
                    b=b+32; 
                else if((b>=97)&&(b<=122))  
                    b=b-32;  
                if(b!=s[a-i-p])
                        return false;                        
            }
        }        
        return true;
    }
};

注:简单题,贼鸡儿烦人的题。faster than 61.64% 。

126. Word Ladder II

 

注:中等题,。faster than 100% 。

127. Word Ladder

 

注:中等题,递归就好了。faster than 100% 。

126. Word Ladder II

 

注:困难题,递归就好了。faster than 100% 。

129. Sum Root to Leaf Numbers

/**
 * 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 sumNumbers(TreeNode* root) {
        
        return digui(root,0);
    }
    
    int digui(TreeNode* root,int k)
    {
        if(!root)
            return k;
        
        int sum=10*k+root->val,p=0;
        
        if(!root->left&&!root->right)
            return sum;
        
        if(root->left)
            p+=digui(root->left,sum);
        
        if(root->right)
            p+=digui(root->right,sum);
        
        return p;
    }
};

注:中等题,递归就好了。faster than 100% 。

130. Surrounded Regions

 

注:中等题,递归就好了。faster than 100% 。

131. Palindrome Partitioning

class Solution {
public:
    vector<vector<string>> partition(string s) {
        
        vector<vector<string>> a;
        vector<string> b;
        digui(a,b,s,0);
        
        return a;
    }
    
    void digui(vector<vector<string>> &a,vector<string> &b,string &s,int k)
    {
        if(k==s.size())
        {
            a.push_back(b);
            return ;
        }
        
        string p;
        for(int i=k;i<s.size();i++)
        {
            p+=s[i];
            string q=p;
            reverse(q.begin(),q.end());
            if(p==q)
            {
                b.push_back(p);
                digui(a,b,s,i+1);
                b.pop_back();
            }
        }
    }
};

注:中等题,被leetcode吓怕了,遇到递归回溯的都不敢直接用。faster than 74.11% 。

132. Palindrome Partitioning II

 

注:困难题,递归就好了。faster than XX% 。

133. Clone Graph

 

注:中等题,递归就好了。faster than 100% 。

134. Gas Station

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
      
        for(int i=0;i<gas.size();i++)
        {
            int sum=0;
            for(int j=i;j<gas.size()+i;j++)
            {
                int p=j;
                if(j>=gas.size())
                    p=j-gas.size();
                sum+=gas[p]-cost[p];
                if(sum<0)
                    break;
            }
            if(sum>=0)
                return i;
        }
        return -1;
    }
};

注:中等题,只会用暴力法,不会用贪心法。faster than 26.34% 。

135. Candy

 

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

136. Single Number/137. Single Number II

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        map<int, int> m;
        for (int i = 0; i < nums.size(); i++) {
            // key 为数组中的值  value为数组中的值出现的次数
            if (!m.count(nums[i])) {
                m[nums[i]] = 1;
            }else {
                m[nums[i]] += 1;
            }
        }
        for (int i = 0; i < nums.size(); i++) {
            if (m[nums[i]] ==  1) {
                return nums[i];
            }
        }
        return -1;
    }
};

注:简单题,如果使用额外空间,一个map就解决了;使用原地算法需要用到位运算,136题用异或可解,137题不会。faster than 7.31% 。

138. Copy List with Random Pointer

/**
 * Definition for singly-linked list with a random pointer.
 * struct RandomListNode {
 *     int label;
 *     RandomListNode *next, *random;
 *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
 * };
 */
class Solution {
public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        /*(一对一的)哈希表map 空间O(n)*/
        
        //判空
        if(head == NULL) return NULL;
        
        //复制原链表,创建一个新链表,整个过程中两个链表是平行的,通过哈希表关联起来
        map<RandomListNode*,RandomListNode*> map;
        RandomListNode* cur = head;
        
        //创建和原链表一样的结点,利用哈希表建立原链表结点和拷贝结点的一一对应关系
        while(cur!= NULL)
        {
            RandomListNode* copy_cur = new RandomListNode(cur->label) ;
            map[cur]=copy_cur;//下标功能强大,支持任意类型,不只是int
            cur = cur->next;
        }
        
        //重新遍历一次链表,复制next和random关系       
        cur = head;//回到表头
        while(cur != NULL)
        {
            map[cur]->next= map[cur->next];
            map[cur]->random = map[cur->random];
            cur = cur->next;
        }
        return map[head];//返回拷贝的新链表的表头
    }
};

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

139. Word Break

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        
        set<string> a;
        vector<int> b(s.size(),-1);
        for(int i=0;i<wordDict.size();i++)
            a.insert(wordDict[i]);
        
        return digui(s,a,b,0);
    }
    bool digui(string& s,set<string>& a,vector<int>& b,int k)
    {
        if(k>=s.size())
            return true;
        
        if(b[k]!=-1)
            return b[k];
        
        string p;
        for(int i=k;i<s.size();i++)
        {
            p+=s[i];
            if(a.find(p)!=a.end())
            {
                if(digui(s,a,b,i+1))
                {
                    b[k]=1;
                    return b[k];                    
                }
            }
        }
        b[k]=0;
        return b[k];
    }
};

注:中等题,递归回溯法超时,使用记忆化搜索。faster than 31.33% 。

140. Word Break II

class Solution {
public:
    vector<string> wordBreak(string s, vector<string>& wordDict) {
        
        set<string> a;
        vector<string> b(s.size(),"1");
        vector<string> c;
        string p;
        for(int i=0;i<wordDict.size();i++)
            a.insert(wordDict[i]);
        
        digui(s,a,b,c,p,0);
        return c;
    }
    
    void digui(string& s,set<string>& a,vector<string>& b,vector<string>& c,string p,int k)
    {
        if(k>=s.size())
        {
            c.push_back(p.substr(1));
            return ;
        }
        
        if(b[k]=="0")
            return ;

        string q;
        for(int i=k;i<s.size();i++)
        {
            q+=s[i];
            if(a.find(q)!=a.end())
            {
                int size=c.size();
                digui(s,a,b,c,p+' '+q,i+1);
                if(c.size()>size)
                    b[k]=p+' '+q;
            }
        }
        if(b[k]!="1")
            return ;
        b[k]="0";
    }
};

注:困难题,这题跟上题一样递归回溯法,但如此简单怎么可能是困难题,其中必藏阴谋,肯定会超时,还是使用记忆化搜索,注意此时的记忆化搜索只需要保存匹配失败的键值。faster than 76.53% 。

 

141. Linked List Cycle

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        
        if(!head)
            return false;
        
        ListNode *slow = head;
        ListNode *fast = head;      
        
        while(fast && fast->next)
        {
            slow = slow->next;
            fast = fast->next->next;
            if(slow == fast)
                return true;
        }
        return false;
    }
};

注:简单题,设置快慢指针即可,如果有环快的肯定会追上慢的。

Runtime: 8 ms, faster than 98.71% of C++ online submissions for Linked List Cycle.

Memory Usage: 9.8 MB, less than 28.88% of C++ online submissions forLinked List Cycle.

 

142. Linked List Cycle II

 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        
        ListNode *m = hasCycle(head);
        
        if(!m)
            return m;
        
        ListNode *p = m;
        p=p->next;
        int num = 1;
        
        while(p!=m)
        {
            p=p->next;
            num++;
        }
        
        ListNode *slow = head;
        ListNode *fast = head;  
        
        while(num--)
            fast = fast->next;
       
        while(fast!=slow)
        {
            fast = fast->next;
            slow = slow->next;
        }
        return slow;
    }

    ListNode *hasCycle(ListNode *head) {
        
        if(!head)
            return NULL;
        
        ListNode *slow = head;
        ListNode *fast = head;      
        
        while(fast && fast->next)
        {
            slow = slow->next;
            fast = fast->next->next;
            if(slow == fast)
                return slow;
        }
        return NULL;
    }
};

 

注:中等题,在141题基础上确认是环,则计算环的节点数目,随后用快慢指针找到入口节点。·

Runtime: 12 ms, faster than 87.20% of C++ online submissions for Linked List Cycle II.

Memory Usage: 9.7 MB, less than 69.53% of C++ online submissions forLinked List Cycle II.

 

143. Reorder List

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    void reorderList(ListNode* head) {
        
        ListNode* p=head;
        
        while(p)
        {
            ListNode* q=p;
            ListNode* m=q;
            while(q&&q->next)
            {
                m=q;
                q=q->next;
            }
            if(m==p)
                break;
            q->next=p->next;
            p->next=q;
            m->next=NULL;
            p=p->next->next;
        }
    }
};

注:中等题,暴力法直接干,前面的写的太多懒得看。faster than 2.02% 。

144. Binary Tree Preorder Traversal

递归版:

/**
 * 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> preorderTraversal(TreeNode* root) {
        
        vector<int> a;
        digui(a,root);
        return a;
    }
    
    void digui(vector<int>& a,TreeNode* root)
    {
        if(!root)
            return ;
        a.push_back(root->val);        
        digui(a,root->left);
        digui(a,root->right);
    }
};

迭代版:

/**
 * 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> preorderTraversal(TreeNode* root) {
        
        vector<int> a;
        stack<TreeNode*> s;
        if(!root)
            return a;
        s.push(root);
        
        while(!s.empty())
        {
            TreeNode* p=s.top();
            s.pop();
            if(p->right)
                s.push(p->right);
            if(p->left)
                s.push(p->left);

            a.push_back(p->val);
        }
        return a;
    }
};

注:中等题,二叉树前序遍历。faster than 100% 。

145. Binary Tree Postorder Traversal

递归版:

/**
 * 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> postorderTraversal(TreeNode* root) {
        
        vector<int> a;
        digui(a,root);
        return a;
    }
    
    void digui(vector<int>& a,TreeNode* root)
    {
        if(!root)
            return ;
      
        digui(a,root->left);
        digui(a,root->right);
        a.push_back(root->val);  
    }
};

迭代版:

​
/**
 * 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> postorderTraversal(TreeNode* root) {
        
        TreeNode*h= root;
        vector<int> q;
        stack<TreeNode*> a; 
        TreeNode*p;
        
        if(!root)
            return q;
        
        a.push(h);
   
        while(!a.empty())
        {
            p=a.top();
            if(p->left)
            {
                a.push(p->left);
                p->left=NULL;
            }
            else
            {
                if(p->right)
                {
                    a.push(p->right);
                    p->right=NULL;
                } 
                else
                {
                    q.push_back(p->val);                    
                    a.pop();
                }
            }

        }
        return q;       
    }
};

​

注:中等题,二叉树后序遍历。faster than 100% 。

146. LRU Cache

 

注:困难题,二叉树后序遍历。faster than 100% 。

147. Insertion Sort List

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* insertionSortList(ListNode* head) {
        
        ListNode* m=new ListNode(0);
        m->next=head;
        ListNode* t=m;
        ListNode* q=head;
        
        while(q&&q->next)
        {
            ListNode* n=q;
            q=q->next;
            ListNode* p=t;
            while(p->next!=q)
            {
                if(q->val<p->next->val)
                {
                    n->next=q->next;
                    q->next=p->next;
                    p->next=q;
                    break;
                }
                p=p->next;
            }
            if(q!=n->next)
                q=n;
        }
        return m->next;
    }
};

注:中等题,插入排序的链表应用,这种题只交换链表节点的值就没意思了。faster than 30.59% 。

148. Sort List

https://blog.csdn.net/feliciafay/article/details/18921799

注:中等题,不想写了,留着下次在写吧。faster than XX% 。

149. Max Points on a Line

 

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

150. Evaluate Reverse Polish Notation

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        
        stack<int> s;
        for(int i=0;i<tokens.size();i++)
        {
            if(tokens[i]=="+")
            {
                int a=s.top();
                s.pop();
                int b=s.top();
                s.pop();                
                s.push(a+b);
            }
            else if(tokens[i]=="-")
            {
                int a=s.top();
                s.pop();
                int b=s.top();
                s.pop();                
                s.push(b-a);
            }
            else if(tokens[i]=="*")
            {
                int a=s.top();
                s.pop();
                int b=s.top();
                s.pop();                
                s.push(b*a);
            }            
            else if(tokens[i]=="/")
            {
                int a=s.top();
                s.pop();
                int b=s.top();
                s.pop();                
                s.push(b/a);
            }
            else s.push(atoi(tokens[i].c_str()));
        }
        return s.top();
    }
};

注:中等题,用一个栈轻松解决。faster than 68.17% 。

 

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值