C++程序:删除排序数组中重复的元素+最佳买股票时机+爬楼梯
第一常规的方法是:从第一个元素开始遍历之后整个数组 判断与当前元素是否相等? 相等的话 就整个数组向前移一位,同时在下一次循环之前递加数减一,从而回到当前的位置进行判断,防止出现三个重复数组的情况下,少判断一次。然后下一次循环就少判断一次,
因为已经前移一位了,具体VS代码如下:
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//
// TEST1_1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include"iostream"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int number=0;
int A[12]={1,1,1,2,2,3,4,5,6,6,7,8};
for(int i=1;i<12-number;i++)
{
if(A[i-1]==A[i])
{
number++;
for(int j=i;j<12-number+1;j++)
{
A[j-1]=A[j];
}
/* A[12-number]=0;*/
i=i-1;
}
}
for(int i=0;i<12-number;i++)
{
cout<<A[i];
}
cout<<'\n';
cout<<number;
//for(int i=0;i<11;i++)
//{
// A[i]=A[i+1];
//}
//A[11]=0;
//for(int i=0;i<12;i++)
//{
// cout<<A[i];
//}
return 0;
}
但是这种方式运行效率不高,导致在lintcode上超出时间限制,所以采用另一种方式,同样的遍历,判断当前元素,与之后的最近的不同的元素替代下一个位置的元素,如果当前元素是唯一的,则会发生下一元素替代自身的情况,并不会影响程序的正确性,Lintcode 的代码如下:
class Solution {
public:
/**
* @param A: a list of integers
* @return : return an integer
*/
int removeDuplicates(vector<int> &nums) {
// write your code here
int ans = 1;
int len = nums.size();
if(len==0)
{
return 0;
}
if(len == 1)
{
return 1;
}
else{
for(int i=1;i<len;i++)
{
if(nums[i]!=nums[ans-1])
{
nums[ans++] = nums[i];
}
}
return ans;
}
}
};
买卖股票的最佳时机:
常见方法,遍历整个数组,计算当前元素与之后的所有元素的差值,取最大即可,若只有一个元素,则为0,若最大小于等于0,则返回0;VS代码如下:
// TEST1_2.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include"iostream"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int a[]={2,2,3,1,2};
int m,s;
m=a[1]-a[0];
s=0;
for(int i=0;i<(sizeof a / sizeof a[0])-1;i++)
{
for(int j=i+1;j<(sizeof a / sizeof a[0]);j++)
{
s=a[j]-a[i];
if(m<s)
{
m=s;
}
}
}
cout<<m;
return 0;
}
但是这种方式因为遍历的原因使得执行时间太长,效率不高,我们可以使用max和min函数来减少一个for循环,从而提高效率,定义一个标准值为0,即最低赚0,计算下一元素与当前元素差值,与0比较,取大的,然后比较当前元素与遍历的下一元素的大小,取小的,使得永远是下一元素减去,之前所有元素的最小值,然后比较取最大差值,lintcode代码如下:
class Solution {
public:
/**
* @param prices: Given an integer array
* @return: Maximum profit
*/
int maxProfit(vector<int> &prices) {
// write your code here
int l,s,m=0;
int k=prices.size();
if(k==0||k==1)
{
return 0;
}
else
{
s=prices[0];
for(int i=1;i<k;i++)
{
l=prices[i];
m=max(m,l-s);
s=min(s,l);
}
return m;
}
}
};
爬楼梯,常见方法:设楼梯高度为n,将n进行拆分,以n中2的个数为准,从0个2遍历到n/2为止,计算剩余多少个1,求得1和2 当前的总数,计算当前情况的所有排列的组合数,与0相加,循环后即可求得结果,但在lintcode里,当数组长度大于等于20时程序出错,目前还不知道什么原因,所以使用递归的方式来做,会发现这样的规律,这次爬的种类数等于上次的加上上一次的,所以用递归如下:
class Solution {
public:
/**
* @param n: An integer
* @return: An integer
*/
int climbStairs(int n) {
if (n == 0 || n == 1) return 1;
if (n < 0) return 0;
return climbStairs(n - 1) + climbStairs(n - 2);
}
};
但是会超出时间限制,所以用一个数组或者变量来储存每次的结果,当然变量会更好,所以采用变量的形式,代码如下:
class Solution {
public:
/**
* @param n: An integer
* @return: An integer
*/
int climbStairs(int n) {
// write your code here
int first = 0;
int second = 1;
while(n>0){
second=first+second;
first=second-first;
n--;
}
return second;
}
};
这道题用了动态规划的方法,并不是很懂,去查了一下:把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解,创立了解决这类过程优化问题的新方法——动态规划。