LeetCode(三)
LeetCode75 Day3
151.反转字符串中的单词
给你一个字符串 s
,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s
中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s
中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
示例 1:
1 | 输入:s = "the sky is blue" |
示例 2:
1 | 输入:s = " hello world " |
示例 3:
1 | 输入:s = "a good example" |
提示:
1 <= s.length <= 104
s
包含英文大小写字母、数字和空格' '
s
中 至少存在一个 单词
进阶:如果字符串在你使用的编程语言中是一种可变数据类型,请尝试使用 O(1)
额外空间复杂度的 原地 解法。
1 | //反转字符串函数 |
- 移除多余空格:
- 使用两个指针
fast
和slow
来遍历字符串s
。 fast
指针用于找到第一个非空格字符的位置,将其复制到slow
指针所指向的位置,并同时递增两个指针。- 当遇到连续的空格时,
fast
指针继续递增直到找到一个非空格字符。 - 这样就实现了移除单词之间多余的空格,并将结果保存在原始的字符串
s
中。
- 使用两个指针
- 反转整个字符串:
- 使用
reverse
函数来反转整个字符串,调用方式为reverse(s, 0, slow - 1)
。 - 这个
reverse
函数会将s
中从索引0
到slow - 1
的部分进行反转。
- 使用
- 反转每一个单词:
- 使用一个循环来遍历字符串
s
。 - 当遇到空格或者到达字符串末尾时,就找到了一个单词的结束位置。
- 调用
reverse
函数来反转当前单词的字符,调用方式为reverse(s, i, j - 1)
,其中i
是当前单词的起始位置,j
是当前单词的结束位置(不包括空格)。 - 然后更新循环变量
i
为j
,以继续寻找下一个单词。
- 使用一个循环来遍历字符串
238.除自身以外数组的乘积
给你一个整数数组 nums
,返回 数组 answer
,其中 answer[i]
等于 nums
中除 nums[i]
之外其余各元素的乘积 。
题目数据 保证 数组 nums
之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。
请 不要使用除法,且在 O(*n*)
时间复杂度内完成此题。
示例 1:
1 | 输入: nums = [1,2,3,4] |
示例 2:
1 | 输入: nums = [-1,1,0,-3,3] |
提示:
2 <= nums.length <= 105
-30 <= nums[i] <= 30
- 保证 数组
nums
之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内
进阶:你可以在 O(1)
的额外空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组 不被视为 额外空间。)
1 | int* productExceptSelf(int* nums, int numsSize, int* returnSize) int* productExceptSelf(int* nums, int numsSize, int* returnSize) { |
- 首先,函数通过
malloc
动态分配了一个大小为numsSize
的整型数组result
,用于存储最终的结果。同时将returnSize
指向的位置设置为numsSize
,表示返回的数组大小为原始数组的大小。 - 接着,代码进入第一个循环,遍历原始数组
nums
。在这个循环中,通过变量temp
记录当前元素之前所有元素的乘积。遍历过程中,将temp
的值乘以当前元素之前所有元素的乘积,并将结果存储到result
数组对应的位置。这样,第一个循环结束后,result
数组中存储的是每个元素之前所有元素的乘积。 - 然后,代码进入第二个循环,这次从数组的最后一个元素开始向前遍历。在这个循环中,通过变量
temp
记录当前元素之后所有元素的乘积。遍历过程中,将temp
的值乘以当前元素之后所有元素的乘积,并将结果与之前存储在result
数组中的值相乘,更新result
数组对应位置的值。这样,第二个循环结束后,result
数组中存储的是每个元素之前所有元素和之后所有元素的乘积。 - 最后,函数返回
result
数组,完成了对原始数组的处理并得到了结果数组。
还有一种代码:
1 | /** |
- 首先,代码定义了一个全局数组
ra
,用于存储最终的结果。这个数组的大小被设置为 100000,可以存储较大规模的结果。 - 接着,在第一个
for
循环中,将ra
数组中的所有元素初始化为1。这是为了在后续的计算中,每个元素都能乘以一个初始值。 - 然后,代码定义了两个变量
pre
和suf
,分别用于记录当前元素前面所有元素的乘积和当前元素后面所有元素的乘积。这两个变量初始化为1。 - 进入第二个
for
循环,这里的循环从索引1开始,因为第一个元素的前面没有元素了。在这个循环中,代码通过不断更新pre
和suf
的值,来计算当前元素之前所有元素的乘积和之后所有元素的乘积。 - 在每次循环中,代码将
pre
乘以当前元素的前一个元素,并将suf
乘以当前元素的后一个元素。然后,将这两个乘积分别与ra
数组中对应位置的元素相乘,并将结果保存到ra
数组中对应的位置。 - 最后,函数将
numsSize
赋值给returnSize
,表示返回的数组大小为原始数组的大小,并返回ra
数组。
这段代码定义了一个大小为 100,000 的静态整型数组 ra
。它可能用于存储计算结果,但是在实际情况中,它可能会导致内存溢出或者其他问题,因为数组的大小未知,同时最后,函数设置了返回数组的大小,并返回指向 ra
的指针。但是这里的问题是,ra
是一个本地数组,它的内存生存期在函数返回时结束,因此返回指向它的指针是不安全的,应该使用动态内存分配(例如 malloc()
)来分配一个新的数组来存储结果。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 空白!