本篇博客会讲解力扣“2574. 左右元素和的差值”的解题思路,这是题目链接。
先来审题:
以下是输出示例:
以下是提示:
本题的关键在于,“左和”和“右和”是如何变化的。下面我通过代码来演示。
一上来,我们应该求下表为0的元素的“左和”和“右和”。
int* leftRigthDifference(int* nums, int numsSize, int* returnSize){
// 下标0元素的左和
int left = 0;
// 下标0元素的右和
int right = 0;
for (int i = 1; i < numsSize; ++i)
{
right += nums[i];
}
}
接下来,开辟结果数组。
int* leftRigthDifference(int* nums, int numsSize, int* returnSize){
// 下标0元素的左和
int left = 0;
// 下标0元素的右和
int right = 0;
for (int i = 1; i < numsSize; ++i)
{
right += nums[i];
}
int* ret = (int*)malloc(sizeof(int) * numsSize);
*returnSize = numsSize;
}
遍历结果数组,把结果放进去。
int* leftRigthDifference(int* nums, int numsSize, int* returnSize){
// 下标0元素的左和
int left = 0;
// 下标0元素的右和
int right = 0;
for (int i = 1; i < numsSize; ++i)
{
right += nums[i];
}
int* ret = (int*)malloc(sizeof(int) * numsSize);
*returnSize = numsSize;
for (int i = 0; i < numsSize; ++i)
{
ret[i] = abs(left - right);
}
return ret;
}
下面是关键:“左和”和“右和”是如何变化的?
- 对于“左和”,下标为1的元素的“左和”比起下标为0的元素的“左和”,多加了下标为0的元素,所以“左和”的变化规律是:
left += nums[i];
。 - 对于“右和”,下标为1的元素的“右和”比起下标为0的元素的“右和”,需要减去下标为1的元素,所以“右和”的变化规律是:
right -= nums[i + 1];
。
写进代码:
int* leftRigthDifference(int* nums, int numsSize, int* returnSize){
// 下标0元素的左和
int left = 0;
// 下标0元素的右和
int right = 0;
for (int i = 1; i < numsSize; ++i)
{
right += nums[i];
}
int* ret = (int*)malloc(sizeof(int) * numsSize);
*returnSize = numsSize;
for (int i = 0; i < numsSize; ++i)
{
ret[i] = abs(left - right);
left += nums[i];
right -= nums[i + 1];
}
return ret;
}
但是这样过不了,错误信息如下:
=================================================================
==20==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000020 at pc 0x55f869e36270 bp 0x7fff04e380c0 sp 0x7fff04e380b0
READ of size 4 at 0x602000000020 thread T0
#2 0x7f4221987082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
0x602000000020 is located 0 bytes to the right of 16-byte region [0x602000000010,0x602000000020)
allocated by thread T0 here:
#0 0x7f42225cf808 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:144
#3 0x7f4221987082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
Shadow bytes around the buggy address:
0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa 00 00[fa]fa 00 00 fa fa fa fa fa fa fa fa
0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==20==ABORTING
这是为什么呢?其实,当计算到下标为size-1的元素的“右和”时,执行right -= nums[i+1];
,i+1已经越界了。所以最后一个右和要单独算。
int* leftRigthDifference(int* nums, int numsSize, int* returnSize){
// 下标0元素的左和
int left = 0;
// 下标0元素的右和
int right = 0;
for (int i = 1; i < numsSize; ++i)
{
right += nums[i];
}
int* ret = (int*)malloc(sizeof(int) * numsSize);
*returnSize = numsSize;
for (int i = 0; i < numsSize - 1; ++i)
{
ret[i] = abs(left - right);
left += nums[i];
right -= nums[i + 1];
}
// 防止越界,最后一个数据单独计算
ret[numsSize - 1] = abs(left);
return ret;
}
这样就过了。文章来源:https://www.toymoban.com/news/detail-442510.html
总结
- 明白迭代时变量的变化规律。
- 如果可能越界,边界元素可以单独计算。
感谢大家的阅读!文章来源地址https://www.toymoban.com/news/detail-442510.html
到了这里,关于算法之美:探究左右元素和的差值的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!