一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情。
前言
双指针基于暴力解法的优化
其指的是利用两个变量在线性结构上遍历,进而可以解决的某些问题。
一般可以用于降低时间复杂度
今天又刷了三道题,分享分享
例1_反转字符串:
🌱题目要求:
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例 1:
- 输入:
s = ["h","e","l","l","o"]- 输出:
["o","l","l","e","h"]
示例 2:
- 输入:
s = ["H","a","n","n","a","h"]- 输出:
["h","a","n","n","a","H"]
提示:
1 <= s.length <= 105s[i]都是 ASCII 码表中的可打印字符
💡思路1:
- 翻转前:[
s[0],s[1],s[2] … s[n-1]]- 翻转后:[
s[n-1],s[n-2],s[n-3] … s[0]]- 通过观察,我们得出这道题的解法:
- 我们定义两个指针
i和j(或者说是数组的索引)- 分别指向数组的首元素和末元素
- 然后两指针边交换元素,边向中间移动
- 当
i<j时,反转结束,返回数组即可。
🌳代码实现
例2_轮转数组:
🌱题目要求:
给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
示例 1:
输入:
nums = [1,2,3,4,5,6,7],k = 3输出:
[5,6,7,1,2,3,4]解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]
示例 2:
输入:
nums = [-1,-100,3,99],k = 2输出:
[3,99,-1,-100]解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]
提示:
1 <= nums.length <= 105
-231 <= nums[i] <= 231 - 1
0 <= k <= 105
💡思路1
- 首先应该想到,如果
k值大于数组长度时,我们应该更新k值,即k%=nums.size()将重复部分去掉。- 接着,以题目为例:
nums = [1,2,3,4,5,6,7],k = 3- 我们先反转一次得到
nums = [7,6,5,4,3,2,1]- 把翻转后的数组看作两部分
- 如:
[7,6,5][4,3,2,1]- 再分别翻转
- 最后就可以得到最终结果
[5,6,7,1,2,3,4]
🌳代码实现
💡思路2
- 我们新建立一个数组
new_arr[],- 然后通过for循环遍历原数组
nums[]- 将原数组的元素
nums[i]放到新数组new_arr[(i+k)%n]中- 最后将
new_arr[]中的元素复制到nums[]即可。
🌳代码实现
例3_移动零
🌱题目要求:
示例 1:
- 输入:
nums = [0, 1, 0, 3, 12]- 输出 :
[1, 3, 12, 0, 0]
示例 2 :
- 输入 :
nums = [0]- 输出 :
[0]
提示 :
1 <= nums.length <= 104-231 <= nums[i] <= 231 - 1
💡思路1
- 题目的要求是:将数组中的零全部移动到末尾,其余数字的顺序不要变
- 我们定义两个指针
i和j,分别初始化为0- 指针
i用来遍历整个nums数组- 指针
j用来指向处理后的数组- 利用
while循环,遍历数组nums- 循环里面,利用
if语句,判断元素nums[i]是否不为零- 如果元素是非零值,就将该元素
nums[i]赋值给nums[j],同时j指向下一位元素;- 接着
i++;指向下一个元素- 如此反复,直到遍历完整个数组
- 最后再将
nums[j]后面的元素全部赋值为0
🌳代码实现
💡思路2
- 我们定义两个指针
i和j,分别初始化为0- 然后利用while循环来遍历数组
nums[]- 接着利用
if语句,判断nums[i]是否不为零- 当遇到非零值
nums[i]时,就将nums[i]与nums[j]交换一下- 接着
j++指向下一位元素- 然后是
i++- 当
while循环结束后,就已经完成题目要求了
🌳代码实现
写成动态图是这样的:
好了,三道例题已经看完,你的解题思路是什么那,快来评论区一起讨论吧!