No.2 设计包含min函数的栈 No.3 求子数组的最大和

◇◆丶佛笑我妖孽 提交于 2019-11-29 01:47:42

No.2 设计包含min函数的栈

定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。

要求函数min、push以及pop的时间复杂度都是O(1)。

Answer:

这题的思想的核心就是自己设计了元素的类型:MinStackElement

然后自己实现栈元素的插入push、退出pop、返回栈中最小的元素值MinStackElement:

struct MinStackElement
{
    int data;
    int min;
}

struct MinStacak
{
    MinStackElement *data;
    int maxsize;  //该栈的最大容量
    int size;    //该栈当前的容量
}

MinStack MinStackInit(int maxSize)
{
    MinStack stack;
    stack.maxsize = maxSize;
    stack.data = (MinStackElement *)malloc(sizeof(MinStackElement)*maxSize);
    stack.size = 0;
    return stack;
}

void MinStackFree(MinStack stack)
{
    free(stack.data);
}

void MinStackPush(MinStack stack,int element)
{
    if(stack.size + 1 == stack.maxsize)
        error("out of range!");

    MinStackElement *p = stack.data[stack.size];
    p->data = element;
    p->min = (stack.size == 0)?element:stack.data[size-1].min;

    if(element < p->min)
       p->min = element;
    stack.size++;
}

int MinStackPop(MinStack stack)
{
    if(stack.size == 0)
        error("empty stack!");

    return stack.data[--stack.size].data;
}

int MinStackMin(MinStack stack)
{
    if(stack.size == 0)
        error("empty stack!");

    return stack.data[stack.size-1].min;
}

这题主要是学习了一个这样的构造新元素的思想,通过构造新的元素类型来以空间换时间;

这里每个元素都分别保存了当该元素处于栈顶时整个栈的最小元素值,占用了一定的空间,但是可以以O(1)的时间复杂度获得栈当前的最小元素,以空间换时间!


No.3 求子数组的最大和

输入一个整型数组,数组中有正数也有负数。

数组中的连续的一个或多个整数组成一个子数组,每个子数组都有一个和。

求所有子数组的和的最大值。要求时间复杂度为O(n)。例如:

输入的数组为1,-2,3,10,-4,7,2,-5,和最大的子数组为3,10,-4,7,2;

因此输出为该子数组的和18。


ANSWER:

这题初感觉似乎要多遍历几遍,但是如果那样的话时间复杂度是不满足要求的;这里的思想就是贪心策略;

贪心策略有的时候总是不那么明显,不是很容易能够说明白这是怎样的一个过程;

我就拿答案来分析吧,就当是按图索骥,这样来学习和体会作者的思想;

我们一开始要设置一个变量sum,用于记录当前我们考察的子数组的和;

max变量:用于记录当前我们已经找到的子数组和中的最大值

因为整个数组包含正数和负数,所以我们要找的的max一定是正的,按照这种思想,那么每当sum为负时,我们就应该将其归零,因为如果加上前面的这个和为负的子数组,只会给后面考察的子数组增添”负担“,那么这样的话,就应该在这个时候将sum重新置为0,这样从下一个数开始考察下面的子数组;

那如果当前考察的sum为正的或者0又该如何处理?以及思想是什么呢?

如果为0:那么至少当前考察的这个子数组不会给后面的子数组带来”负担“,所以sum可归零也可不归零

如果为正:那么可以肯定当前考察的子数组会给后面的子数组带来”益处“,即使sum变大,所以应该保留,继续向下考察

将上面的思想翻译成代码就是:

int maxSubarry(int *data,int len)
{
	int max = (1<<31);
	int sum = 0;
	
	for(int i=0;i!=len;++i)
	{
		sum += data[i];
		if(sum < 0)
			sum = 0;
		if(sum > max)
			max = sum;
	}

	return max;
}


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!