算法基础题详解,下面都是以函数体现,亲测无误,有问题可以联系博主

算法基础题详解,下面都是以函数体现,亲测无误,有问题可以联系博主

题1:旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称为数组的旋转。输入一个递增排序的数组的一个旋转输出旋转数组的最小值。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.

解析:

1 2 3 4 5 6 7 8 ==>3 4 5 6 7 8 1 2(indexOfmid=6,<indexOfmid有序,>indexOfmid无序)
==>7 8 1 2 3 4 5 6(indexOfmid=2 <indexOfmid无序 >indexOfmid有序)

0011111111==>1111111100

此算法不适用于mid与两头相等的例子
例:0111111==>10111111:此时应用扫描法
总结:if(indexOfmid>beigin)左侧有序,否则右侧有序

代码:

int min(int arr[],int n) {
int begin = 0;
int end = n - 1;
int min;
//考虑没有旋转这种特殊的旋转
if (arr[begin]<arr[end])
{
return arr[begin];
}
while (begin+1<end)
{
//二分法,获取中间数
int indexOfmid = begin + ((end - begin) >> 1);

	//当arr[indexOfmid]>arr[begin]左侧有序,否则右侧有序
	if (arr[indexOfmid]>=arr[begin])
	{
		begin = indexOfmid;
	}
	else
	{
		end = indexOfmid;
	}
}
min = arr[end];
return min;

}

解决上面遗留的问题

//如果中间的值和两头都相等,则用扫描法实现
	if ((!(arr[indexOfmid] ^ arr[begin]))&& (!(arr[indexOfmid] ^ arr[end])))
	{
		min = arr[begin++];
		while (begin<end+1)
		{
			if (min>arr[begin])
			{
				min = arr[begin];
			}
			begin++;
		}
		return min;
	}

题二:在有空字符串的有序字符串数组中查找

有个排序后的字符串数组,其中无规律散步着一些空字符串,编写一个方法,找出给定字符串(肯定不是空字符串)的索引

此题没难度,直接用二分法,但是注意空字符串是无规律分部的

代码:

int indexOf(string str[], string p, int n) {
int begin = 0;
int end = n - 1;
int indexOfmid;
while (begin <= end)
{
indexOfmid = begin + ((end - begin) >> 1);
if (str[indexOfmid]._Equal(""))
{
indexOfmid++;
//注意,千万注意,这块容易报死循环
if (indexOfmid > end)
{
return -1;
}
}
if (str[indexOfmid]._Equal§)
{
return indexOfmid;
}
else if ((str[indexOfmid]._Equal§) > 0)
{
end = indexOfmid - 1;
}
else
{
begin = indexOfmid + 1;
}

}
return -1;

}

题三:最长连续递增子序列的长度

输入:是一个部分有序的数组
输出:一个整数
例:
输入:1 9 2 5 7 3 4 6 8 0
输出:4

解释:{1 9 2 5 7 3 4 6 8 0}中最长递增子序列为{3 4 6 8}

解析:使用双指针法,下面体现了两种方式

代码:

方法一:

int maxLength(int arr[],int n) {
int length = 1;
int temp = 1;
int j,i;
for (i=0,j=i+1; j < n;)
{
//方法一:i,j同时移动
if (arr[j]>=arr[i])
{
j++;
i++;
temp++;
}
else
{
if (length<temp)
{
length = temp;
}
temp = 1;
i = j;
j++;
}
}
return length;
}

方法二:

int maxLength(int arr[],int n) {
int length = 1;
int temp = 1;
int j,i;
for (i=0,j=i+1; j < n;)
{
//方法二:I,不动,j移动
if (arr[j] > arr[j - 1])
{
j++;
}
else
{
temp = j - i;
i = j;
j++;
if (length<temp)
{
length = temp;
}
temp = 0;
}
}
return length;
}

题四:设计一个高效的求a的n次幂的算法

用for循环求所需时间为o(n),现在需要优化至o(logn)

从o(n)优化到o(logn),就是从一个个迭代,变成每次减一半

代码:

double power(double a,int n) {
//递归出口
if (n == 0)
{
return 1;
}
double res = a;
int ex = 1;

//指数每次翻倍
//可以翻
while ((ex<<1)<=n)
{
	//翻倍
	res *= res;
	//指数翻倍
	ex <<= 1;
}

//不能翻
//那要判断n-ex是不是为0,不为0,差多少,这里使用的是递归
//在做的时候发现了相似,相似用递归
	return res * power(a, n - ex);

}

下面实现了,求a的n次幂 和 a的-n次幂的整合

代码:

double power(double a,int n) {
//递归出口
if (n == 0)
{
return 1;
}
int flag = n;
if (n<0)
{
n = (~n) + 1;//将n取反
}
double res = a;
int ex = 1;

//指数每次翻倍
//可以翻
while ((ex<<1)<=n)
{
	//翻倍
	res *= res;
	//指数翻倍
	ex <<= 1;
}

//不能翻
//那要判断n-ex是不是为0,不为0,差多少,这里使用的是递归
//在做的时候发现了相似,相似用递归

//正数次幂返回
if (flag>0)
{
	return res * power(a, n - ex);
}
//负数次幂返回
else
{
	res = 1 / res;
	return res*power(a, ex+flag);
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五_谷_丰_登

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值