我正在解决这个脑筋急转弯
给定一个已排序的1索引整数数组非递减顺序,找到两个数字,使它们加起来为具体目标数量。设这两个数字为数字[index1]数字[index2],其中1<=index1<index2<=数字.长度.
返回index1和index2这两个数字加一后的索引作为长度为2的整数数组[index1、index2]。
生成测试时,正好有一个解决方案。你可以不使用同一元素两次。
您的解决方案只能使用恒定的额外空间。
示例1:
Input: numbers = [2,7,11,15], target = 9
Output: [1,2]
Explanation: The sum of 2 and 7 is 9.
Therefore, index1 = 1, index2 = 2.
We return [1, 2].
我的解决方案是给出这个错误:
=================================================================
==31==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000620 at pc 0x000000345e97 bp 0x7ffcd6847990 sp 0x7ffcd6847988
READ of size 4 at 0x602000000620 thread T0
#2 0x7f2c3b9790b2 (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
0x602000000620 is located 0 bytes to the right of 16-byte region [0x602000000610,0x602000000620)
我做了一些研究,发现这通常是由于调用的索引太远(即在您使用的数据结构范围之外(造成的,但由于我使用的是向量,我不明白为什么会出现这种错误。它发生在以下测试用例中:[5,25,75]100.
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
// can have an i that points forward and a j that loops through everything until sum
// is greater
// checking recursively
// if sum greater stop checking (as list is increasing)
// can reset i each time??
// add 1 at the end
vector<int> indices;
int i = 0;
int j = 0;
// for loop on top?
for (int i; i < numbers.size(); i++)
int j = 0;
while (numbers[i] + numbers[j] <= target) {
if (numbers[i] + numbers[j] == target && i != j) {
// some if determining if i or j is greater
// to determine the order in which to push back
indices.push_back(i+1);
indices.push_back(j+1);
return indices;
} else {
j++;
}
}
return indices;
}
};
其他测试都通过了,但这次没有通过。我试图在这里使用两个指针的方法。
这段代码有几个问题,一些简单的语法错误,一些算法问题。
首先,正如其他人所提到的,i
在外部for
循环中未初始化。幸运的是,这永远不会发挥作用,因为你没有环体周围的支架。你的代码等同于
for (int i; i < numbers.size(); i++) {
int j = 0;
}
while (numbers[i] + numbers[j] <= target) {
// ...
}
这可能不是您想要的,所以您需要初始化i
并在循环体周围添加{}
:
for (int i = 0; i < numbers.size(); i++) {
int j = 0;
while (numbers[i] + numbers[j] <= target) {
// ...
}
}
当然,在循环之外也不需要i
和j
的冗余定义。这些变量会被循环中定义的变量隐藏起来,并且永远不会被使用。
当然,这仍然不能解决超出范围的错误。为此,您需要重新思考您的算法。让我们浏览一下,找出问题所在。我只关注内部while
循环。
假设,从您的测试用例中,numbers = {5, 25, 75}
和target = 100
。
第一次迭代:
i = 0
和j = 0
numbers[i] + numbers[j]
->numbers[0] + numbers[0]
->->;5 + 5
->10
。这小于100
,因此进入循环if (10 == 100)
是false
,因此选择了else
分支j++
,所以现在i = 0
和j = 1
第二次迭代:
numbers[i] + numbers[j]
->numbers[0] + numbers[1]
->5 + 25
->CCD_ 26。这小于100
,所以循环继续if (30 == 100)
是false
,因此选择了else
分支j++
,所以现在i = 0
和j = 2
第三次迭代:
numbers[i] + numbers[j]
->numbers[0] + numbers[2]
->CCD_ 36->80
。这小于100
,所以循环继续if (80 == 100)
是false
,因此选择了else
分支j++
,所以现在i = 0
和j = 3
第三次迭代:
numbers[i] + numbers[j]
->numbers[0] + numbers[3]
->吊杆
j
现在超出了numbers
的有效索引范围,因此当您尝试访问numbers[j]
时,程序的行为将变得未定义。在这种情况下,它崩溃了;最好的结果。
正如上述评论所指出的,
for (int i; i < numbers.size(); i++)
此处"int i"隐藏"int i=0;"的上一个本地声明(C4456(,这是不希望的。
问题是,尽管i被绑定到范围[0,n-1],但j不是,当j超过范围时,这可能导致访问违规。
您可以使用下面的代码,这些代码将通过您的所有测试用例。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
//first we will declare an additional vector which will return desired solution
vector<int> mult;
//by using two pointer approach
for(int i = 0; i<=nums.size(); i++){
for(int j = i+1; j<nums.size();j++){
//checking for condition
if(nums[i]+nums[j]==target){
mult.push_back(i);
mult.push_back(j);
j++;
return mult;
}
}
}
return mult;
}
};