Day9:字符串p2-复习双指针

字符串回顾:

  1. 字符串是若干字符组成的有限序列,也可以理解为是一个字符数组

  2. 在C语言中,把一个字符串存入一个数组时,也把结束符 '\0'存入数组,并以此作为该字符串是否结束的标志。

  3. c++ 中,字符串提供了一个size的接口,可以判断字符串长度:

string a = "string";
  for (int i = 0; i < a.size(); i++) {
}

字符串出现过的题目

  1. 反转字符串:使用双指针法实现了反转字符串的操作,双指针法在数组,链表和字符串中很常用。

  2. 使用双指针法在时间复杂度O(n)的情况下完成替换空格。

  3. 其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。

  4. 使用双指针法进行移除操作。

  5. 所以,双指针法是字符串处理的常客。

双指针复习

在以下几种情况下,都用到了双指针:

  1. 数组

    • 移除元素

  2. 字符串

    • 反转字符串

    • 替换数字

  3. 链表

    • 反转链表

  4. N数之和

    • 三数之和

里面大多数题目,我都在前几个博客写过了,这次写两个之前没写过的题目。

15. 三数之和(双指针)

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。

注意: 答案中不可以包含重复的三元组。

示例:

给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]

哈希表思路:(不建议)

  1. 求两数之和:a+b=0,我们用map来存放遍历过的元素

  2. 那么三数之和,我们求 a+b+c=0,相比于两数之和的难点在于,三数之和需要去重

  3. 解题思路如下:去寻找0-(a+b) 是否在map里

  4. 但是这里用哈希法有些难,因为我们需要给a和b去重,去重的可能性非常多,所以很复杂,因此不建议用哈希法来做

双指针法思路: (推荐做法)

  1. 我们有一个数组,然后要在这个数组里找到 a+b+c=0

  2. 然后我们给这个数组排序(递增),(这里我们需要找到三个元素值,而不需要返回下标,所以我们可以先给这个数组排序)

  3. 为什么要排序?

    1. 排序之后,我们用一个for循环,遍历i的位置,得到a(i从第一位开始),然后i的第二位开始为left,末位为right

    2. 然后我们判断:nums[i] + nums[left] + nums[right] 是否 >0

    3. 如果三数相加>0, 那么right-- (right往左移动一位,让和变小一点)

    4. 如果三数相加<0, 那么left++ (left往右移动一位,让和变大一点)

    5. 如果三数相加=0,那就把此时的 nums[i], nums[left], nums[right] 存放到result数组里

  4. 去重:要给abc去重,不能在result中出现重复的元素

伪代码

// 1. 排序
sort(nums);
​
for(i=0; i<nums.size(); i++){
  if(nums[i]>0){  // 如果第一个数组大于0,直接返回
    return
  }
  
  if(i>0 && nums[i] == nums[i-1]) { continue };
  left = i+1;
  right = nums.size()-1;
  
  while(right > left){
    if(nums[i] + nums[left] + nums[right]  > 0):
      right--;
    
    else if(nums[i] + nums[left] + nums[right] <0):
      left++;
    
    else:
      result.push(nums[i],  nums[left], nums[right]);
    
      // 去重
​
  }
     
}


  • 18
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值