剑指offer--和为S的两个数字

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Hanani_Jia/article/details/82594567

题目描述

输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。

输出描述:

对应每个测试案例,输出两个数,小的先输出。

class Solution {

public:

vector<int> FindNumbersWithSum(vector<int> array, int sum) {



int i = 0;

int j = 0;

int end = array.size() ;

int product = -1;//用来存储两个数的乘积

int num1 = 0;

int num2 = 0;

for (i = 0; i < end; i++)

{

for (j = i + 1; j < end; j++)

{

if ((array[i] + array[j]) == sum)

{



if ((array[i] * array[j])<product||product==-1)

{

num1 = array[i];

num2 = array[j];

product = num1*num2;

}

}

}

}



vector<int> a;

if (product == -1)

return a;

else

{

a.push_back(num1);

a.push_back(num2);

return a;

}



}

};

修改一次成功跑过测试,这里就是要注意就是可能会出现不存在的情况,就是我们传入的数组里边根本就没有加起来是S的这时候就要返回一个没有数据的数组,不能返回NULL一类的玩意,那样也通不过编译。为了判断有没有我是把乘积数变成了-1。0在这里感觉并不好,没准会有里边一个数据是0.

  因为之前接触过一个类似的题,但是当时并没有出现说这个数组是个递增数组的情况,所以这里看到递增数组特别注意了一下,感觉这里是可以把你的代码进行优化的,上边代码的复杂度是O(n2)了,复杂度相当的高。

  所以就有了下边进行过一定修改的代码

class Solution {

public:

vector<int> FindNumbersWithSum(vector<int> array, int sum) {

int start = 0;

int end = array.size() - 1;

int product = -1;//用来存储两个数的乘积

int num1 = 0;

int num2 = 0;

while (start < end)

{

if ((array[start] + array[end]) == sum)

{

if ((array[start] * array[end])<product || product == -1)

{

num1 = array[start];

num2 = array[end];

product = num1*num2;

}

break;

}

else

{

if ((array[start] + array[end]) > sum)

{

end--;

}

else

{

start++;

}

}



}

vector<int> a;

if (product == -1)

   return a;

else

{

a.push_back(num1);

a.push_back(num2);

return a;

}

}

};

这时间复杂度就小了不少变成了O(n),这里也有一个需要注意的点,其实这个是我第一个写出来的,但是写着写着我发现我实现不出来,是因为我们可以看到如果是相加和小的话,那就得让数变大,也就是让start往右移动,因为这是一个递增的数组,如果相加和大的话就需要让数变小,让end往左移动。但是你说现在相等了怎么弄,肯定不能说不移动,不移动就是一个死循环,但是移动的话移动哪个都移动,想来想去感觉不合适,就放弃了,

但是后来想明白一个事情,就是你一旦遇到了那就是乘积最小的那个,因为这个很容易理解,假如和是8,1*7,2*6,最大就是4*4这个应该都知道,所以越往中间移动那自然就是最大的,所以我们这里一旦找到相等的直接返回就行。

 我的代码风格也好,简洁度也好都不是很好,有很多地方可以优化,这个会一点一点慢慢的去改。

class Solution {

public:

vector<int> FindNumbersWithSum(vector<int> array, int sum) {

vector<int> result;

int length = array.size();

int start = 0;

int end = length - 1;

while (start < end)

{

if (array[start] + array[end] == sum)

{

result.push_back(array[start]);

result.push_back(array[end]);

break;

}

else if (array[start] + array[end] < sum)

start++;

else

end--;

}

return result;

}

};

这段代码和我第二段代码实现一样的功能但是就简单了很多,这还是需要不断的写来进步的。

下边是今天的选择题:

在循环双链表的 p 所指的结点之前插入 s 所指结点的操作是 。

A.p->prior = s;s->next = p;p->prior->next = s;s->prior = p->prior

B.p->prior = s;p->prior->next = s;s->next = p;s->prior = p->prior

C.s->next = p;s->prior = p->prior;p->prior = s;p->prior->next = s

D.s->next = p;s->prior = p->prior;p->prior->next = s;p->prior = s

这种类型的题说过很多次了,但是今天自己在写的时候还是没用心去想,感觉能做对所以就直接看了两眼凭感觉选了一个,这种插入节点的一定是要让新插入的结点的前后先去找到他应该插入的位置的前后。

两个指针之间插入一个S自然是先让S把这两个元素链接上,再去断开以前存在的红色和绿色的指针。

 

猜你喜欢

转载自blog.csdn.net/Hanani_Jia/article/details/82594567