您的位置:首页 > 编程语言 > Go语言

【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 algorithm 算法