【Leetcode系列之二】Leetcode OJ 11-20
2014-05-23 21:25
260 查看
1. Climbing Stairs
You are climbing a stair case. It takes n steps to reach to the top.Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
由于此题采用递归求解将会进行重复运算,利用空间重和度较高的特点,采用DP(动态规划)方法解答此题。
class Solution { public: int climbStairs(int n) { if(n == 1 || n==2) return n; vector<int> res(n,0); res[0]=1; res[1]=2; for(int i=2;i<res.size();i++) { res[i]=res[i-1]+res[i-2]; } return res[n-1]; } };
2. Single Number II
Given an array of integers, every element appears three times except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
Solution:https://oj.leetcode.com/discuss/857/constant-space-solution
1337c0d2r对此题做了精彩解答,首先是易于理解的程序版本:
int singleNumber(int A[], int n) { int count[32] = {0}; int result = 0; for (int i = 0; i < 32; i++) { for (int j = 0; j < n; j++) { if ((A[j] >> i) & 1) { count[i]++; } } result |= ((count[i] % 3) << i); } return result; }
对于整数来说,共有32位,记录每位1出现的个数,并对其对3取模运算,剩下的各位相加即为答案。
对此程序可以进行进一步简化,利用int32型ones,twos,threes分别记录每位出现的次数,对于threes清除对应的ones和twos,以达到相同的效果:
int singleNumber(int A[], int n) { int ones = 0, twos = 0, threes = 0; for (int i = 0; i < n; i++) { twos |= ones & A[i]; ones ^= A[i]; threes = ones & twos; ones &= ~threes; twos &= ~threes; } return ones; }
3. Maximum Subarray
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.For example, given the array
[−2,1,−3,4,−1,2,1,−5,4],
the contiguous subarray
[4,−1,2,1]has the largest sum =
6.
click to show more practice.
More practice:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
Solution:此题用分治法自己写了一下:
class Solution { public: int subCross(int A[], int left, int right) { if(left == right) return A[left]; int mid = (left+right)/2; int leftMax=A[mid],rightMax=A[mid+1]; int sum =0; for(int i=mid; i>=left; i--) { sum+=A[i]; if(sum>leftMax) leftMax=sum; } sum = 0; for(int i=mid+1; i<right+1; i++) { sum+=A[i]; if(sum>rightMax) rightMax=sum; } return (leftMax+rightMax); } int maxSubArrayDevide(int A[], int left, int right) { if(left == right) return A[left]; return max( max( maxSubArrayDevide(A,left,(left+right)/2) , maxSubArrayDevide(A,(left+right)/2+1,right) ),subCross(A,left,right)); } int maxSubArray(int A[], int n) { return maxSubArrayDevide(A,0,n-1); } };porker2008写的简洁版本如下:
class Solution { public: int maxSubArray(int A[], int n) { // IMPORTANT: Please reset any member data you declared, as // the same Solution instance will be reused for each test case. if(n==0) return 0; return maxSubArrayHelperFunction(A,0,n-1); } int maxSubArrayHelperFunction(int A[], int left, int right) { if(right == left) return A[left]; int middle = (left+right)/2; int leftans = maxSubArrayHelperFunction(A, left, middle); int rightans = maxSubArrayHelperFunction(A, middle+1, right); int leftmax = A[middle]; int rightmax = A[middle+1]; int temp = 0; for(int i=middle;i>=left;i--) { temp += A[i]; if(temp > leftmax) leftmax = temp; } temp = 0; for(int i=middle+1;i<=right;i++) { temp += A[i]; if(temp > rightmax) rightmax = temp; } return max(max(leftans, rightans),leftmax+rightmax); } };
4. Balanced Binary Tree
Given a binary tree, determine if it is height-balanced.
For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
Solution: 对于此题,主要是递归的求解左右深度,若差值大于1则返回false。为避免递归求解和递归求深度双重递归,采用修改引用值的方式。
54ms解法如下:
class Solution { public: bool isBalanced(TreeNode *root) { int l=0, r=0; if(root==NULL) return true; if(!isBalanced(root->right)) return false; if(!isBalanced(root->left)) return false; root->val=1; if(root->right!=NULL) root->val=1+root->right->val; if(root->left!=NULL) root->val=max(root->val, 1+root->left->val); if(root->left!=NULL) l=root->left->val; if(root->right!=NULL) r=root->right->val; if(abs(r-l)>1) return false; return true; } };
5. Minimum Path Sum
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.Note: You can only move either down or right at any point in time.
Solution:https://oj.leetcode.com/discuss/816/minimum-path-sum-how-can-i-reduce-the-memory
Given the dynamic programming formula
f[i][j]=min(f[i-1][j],f[i][j-1])+grid[i][j]:
Assume that you are populating the table row by row, the current value (
f[i][j])
will be used immediately in the calculation of
f[i][j+1], so there is no need to
store all the previous column values.
Therefore, you can do it in linear space complexity. Below is a sample code courtesy of Linfuzki@.
class Solution { public: int minPathSum(vector<vector<int> > &grid) { if (grid.empty() || grid[0].empty()) return 0; int m = grid.size(), n = grid[0].size(); vector<int> dp(n + 1, INT_MAX); dp[1] = 0; for (int i = 0; i < m; ++i) for (int j = 0; j < n; ++j) dp[j + 1] = min(dp[j + 1], dp[j]) + grid[i][j]; return dp.back(); } };
6. Sort Colors
Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue.Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.
Note:
You are not suppose to use the library's sort function for this problem.
Follow up:
A rather straight forward solution is a two-pass algorithm using counting sort.
First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's.
Could you come up with an one-pass algorithm using only constant space?
Solutions: 该问题可以考虑有一组按提述排序好的数字,有x个0,y个1,z个2 。考虑1起始的位置为i,2起始的位置为j。对于在尾部插入一个新元素,如果是2可以直接将尾部值置为2 。若为1则将j处的2置为1令j自增1,并将尾部值置为2 。若为0则将i处的1置为0令i自增1,将j处的2置为1令j自增1,并将尾部值置为2 。 考虑算法均将尾部值置为2可以将顺序提前然后再分支选择。
class Solution { public: void sortColors(int A[], int n) { int i=-1, j=-1; for(int p = 0; p < n; p++) { int v = A[p]; A[p] = 2; if (v == 0) { A[++j] = 1; A[++i] = 0; } else if (v == 1) { A[++j] = 1; } } } };
7. Merge Sorted Array
Given two sorted integer arrays A and B, merge B into A as one sorted array.Note:
You may assume that A has enough space (size that is greater or equal to m + n) to hold additional elements from B. The number of elements initialized in A and B are m andn respectively.
Solution:
对于此题,如果不使用额外的空间,考虑从数组的最右边,也就是最大值出现的地方开始向下循环,将大值依次赋予最右边,并更改下标。
class Solution { public: void merge(int A[], int m, int B[], int n) { for (int idx = m + n - 1; idx >= 0; idx--) { if (m <= 0) { A[idx] = B[--n]; } else if (n <= 0) { break; } else if (A[m-1] < B[n-1]) { A[idx] = B[--n]; } else { A[idx] = A[--m]; } } } };
相关文章推荐
- LeetCode 笔记系列 20 Interleaving String [动态规划的抽象]
- 算法系列(20) Leetcode 575. Distribute Candies
- ZT:“再看OA”系列讲座之二:OA为何用不好?
- 水木--给Linux新手 [系列之二]
- 微软软件实现技术授课系列内容之二:C++ Best Coding Practice
- 《让僵冷的翅膀飞起来》系列之二——从实例谈Adapter模式
- Microsoft .Net Remoting系列专题之二:Marshal、Disconnect与生命周期以及跟踪服务
- CMMI实施系列之二:EPG和QA是CMMI实施中两个并驾齐驱的轮子
- 手把手教你捕获数据包【数据包的游戏系列之二】 by PiggyXP【小猪】
- 定制SPS实战记录 系列之二
- UML复习系列之二(工具使用)【原创】
- VB真是想不到系列之二:VB《葵花宝典》--指针技术
- 手把手教你捕获数据包(下)【数据包的游戏系列之二】
- 开发Foxmail与Pocket PC的同步软件系列之二--FreeMail
- 开发Foxmail与Pocket PC的同步软件系列之二--FreeMail
- JAVA/JSP学习系列之二(Tomcat安装)
- (C++的对话)Solmyr 的小品文系列之二:模棱两可的陷阱
- 手把手教你捕获数据包(上)【数据包的游戏系列之二】
- 微软软件实现技术授课系列内容之二:C++ Best Coding Practice
- JAVA/JSP学习系列之二(Tomcat安装)