栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

双指针C++

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

双指针C++

双指针夹逼定理 977. 有序数组的平方

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

示例 1:

输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
示例 2:

输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]

提示:

1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 已按 非递减顺序 排序

进阶:

请你设计时间复杂度为 O(n) 的算法解决本问题

题解
//原题本来就是排序的,只不过有负数;
//kk是从后往前的下标;
//从前往后插
class Solution {
public:
    vector sortedSquares(vector& nums) {
    vector n1(nums.size());
    int rr=nums.size()-1;
    int ll=0; int kk=nums.size()-1;
while(ll<=rr)
{
if(abs(nums[ll])>abs(nums[rr])){n1[kk]=(nums[ll]*nums[ll]);ll++;kk--;}
if(abs(nums[ll])<=abs(nums[rr])){n1[kk]=(nums[rr]*nums[rr]);rr--;kk--;}
}
    return n1;
    }
};
283. 移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:

输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:

必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。

题解
class Solution {
public:
    void moveZeroes(vector& nums) {
int n=nums.size();
int a=0;//aa是从前往后的下标;
for(int i=0;i 
167. 两数之和 II - 输入有序数组 

给定一个已按照 非递减顺序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。

函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。

你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。

示例 1:

输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
示例 2:

输入:numbers = [2,3,4], target = 6
输出:[1,3]
示例 3:

输入:numbers = [-1,0], target = -1
输出:[1,2]

提示:

2 <= numbers.length <= 3 * 104
-1000 <= numbers[i] <= 1000
numbers 按 非递减顺序 排列
-1000 <= target <= 1000
仅存在一个有效答案

题解
class Solution {
public:
    vector twoSum(vector& numbers, int target) {
      int n=numbers.size();
      int a=0,b=n-1;
      while(atarget)        b--;
        else if(numbers[a]+numbers[b]==target) return vector{a+1,b+1};
        else                                    a++;
      }
          return vector{-1, -1};
    }
};
344. 反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 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 <= 105
s[i] 都是 ASCII 码表中的可打印字符

题解
class Solution {
public:
    void reverseString(vector& s) {
        int n=s.size();
    for(int i=0;i 
557. 反转字符串中的单词 III 

给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。

示例:

输入:“Let’s take LeetCode contest”
输出:“s’teL ekat edoCteeL tsetnoc”

提示:

在字符串中,每个单词由单个空格分隔,并且字符串中不会有任何额外的空格。

题解
class Solution {
public:
    string reverseWords(string s) {
        int n=s.size();int a=0,b=-1;
          for(int i=0;i 
189. 旋转数组 

给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。

进阶:

尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?

示例 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 <= 2 * 104
-231 <= nums[i] <= 231 - 1
0 <= k <= 105

题解
class Solution {
public:
    void rotate(vector& nums, int k) {
        int n=nums.size();
        if(n==1)
        return;
        k=k%n;//经过总结规律。刚开大于n时,相当取n的余;
        int a=0,b=n-1;//翻转全部。
        while(a 
11. 盛最多水的容器 

给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器。

示例 1:

输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

题解
class Solution {
public:
    int maxArea(vector& height) {
 int a=0,b=height.size()-1;
 int max=0;
 while(a 
16. 最接近的三数之和 

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

示例:

输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。

提示:

3 <= nums.length <= 10^3
-10^3 <= nums[i] <= 10^3
-10^4 <= target <= 10^4

题解
class Solution {
public:
    int threeSumClosest(vector& nums, int target) {
   int mini=10000,min1;
   int n=nums.size();
    sort(nums.begin(),nums.end());
   for(int i=0;itarget)b--;
          else return target;

     }
   }
   return min1;
    }
};

##面试题 01.05. 一次编辑
字符串有三种编辑操作:插入一个字符、删除一个字符或者替换一个字符。 给定两个字符串,编写一个函数判定它们是否只需要一次(或者零次)编辑。

示例 1:

输入:
first = “pale”
second = “ple”
输出: True

示例 2:

输入:
first = “pales”
second = “pal”
输出: False

题解
class Solution {
public:
    bool oneEditAway(string first, string second) {
    int m=first.size(),n=second.size();
    // if(first.empty()&&second.size()==1) return true;
    // if(second.empty()&&first.size()==1) return true;
    if(n>m)swap(first,second);
    if(first.size()-second.size()>1)//两字符串长度相差二
     return false;
    else if(first.size()==second.size())//两个字符串一样长
    {
        int sum=0;
     for(int i=0;i1)return false;}
     return true;
    }
else//两字符串长度相差一。
{
int a=0,b=n-1;
while(a<=b&&first[a]==second[a]) a++;//从前往后遍历,
while(a<=b&&first[b+1]==second[b]) b--;//从后往前便利,如果错误之处有两个,则A必小于B,如果只有一次错误,则A等于B加一。
return a>b;
}
  
    }
};
面试题 16.16. 部分排序

给定一个整数数组,编写一个函数,找出索引m和n,只要将索引区间[m,n]的元素排好序,整个数组就是有序的。注意:n-m尽量最小,也就是说,找出符合条件的最短序列。函数返回值为[m,n],若不存在这样的m和n(例如整个数组是有序的),请返回[-1,-1]。

示例:

输入: [1,2,4,7,10,11,7,12,6,7,16,18,19]
输出: [3,9]
提示:

0 <= len(array) <= 1000000

题解
class Solution {
public:
    vector subSort(vector& array) {
       int n=array.size();
       if(n==1||n==0)//刚刚只有一个或没有元素的时候,我们直接返回{-1,-1}说明他就不需要再排序
       return {-1,-1};
        int i=1,j=n-2;//相当于我们先找出开始混乱的地方。但没有混乱的地方不一定排不排。初始第一个元素和最后一个元素是有序的。逐渐加入游戏的队伍。
        while(iarray[j+1])break;j--;}j++;//从右往左咋说开始混乱的地方
        int max1=array[0];int min1=array[n-1];//找出混乱的最大值和最小
        for(int k=i;k<=j;k++)
        {
            if(array[k]max1)max1=array[k];
        }
        int m=i+1,m2=j-1;//首先给个默认值
        for(int k=0;k<=i;k++)//确定左端开始排序的下标
        {
           if(array[k]>min1)
            {
                m=k;
                break;
            }
        }
        for(int k=n-1;k>=j;k--)//确定右端开始排序的下标
        {
           if(array[k] 
面试题 10.01. 合并排序的数组 

给定两个排序后的数组 A 和 B,其中 A 的末端有足够的缓冲空间容纳 B。 编写一个方法,将 B 合并入 A 并排序。

初始化 A 和 B 的元素数量分别为 m 和 n。

示例:

输入:
A = [1,2,3,0,0,0], m = 3
B = [2,5,6], n = 3

输出: [1,2,2,3,5,6]
说明:

A.length == n + m

题解
class Solution {
public:
    void merge(vector& A, int m, vector& B, int n) {
    int i=m-1,j=n-1;int max1=m+n-1;
    int l1=0;if(m==0)while(l1=0&&i>=0)
    {
        if(A[i]>=B[j]){ A[max1]=A[i];  max1--;  i--;   }//逆向插入,把最大的插入向前依次插入
        else { A[max1]=B[j];  max1--;   j--;} 
    }
    if(j>=0)while(j>=0){A[max1]=B[j]; max1--;  j--;  }//当一个已经插完了,如果是A剩下了那么A就不需要再插了
                                                 //如果是B剩下的,就应该全部把剩下的给全部剩下的A;
    }
};
快慢指针 876. 链表的中间结点

给定一个头结点为 head 的非空单链表,返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。

示例 1:

输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
注意,我们返回了一个 ListNode 类型的对象 ans,这样:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.
示例 2:

输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。

提示:

给定链表的结点数介于 1 和 100 之间。

题解
class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        ListNode *a=head;
        ListNode *b=head; 
        while(b!=NULL&&b->next!=NULL)
        {
            a=a->next;
            b=b->next->next;
        }
        return a;
    }
};
19. 删除链表的倒数第 N 个结点

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

进阶:你能尝试使用一趟扫描实现吗?

示例 1:

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:

输入:head = [1], n = 1
输出:[]
示例 3:

输入:head = [1,2], n = 1
输出:[1]

提示:

链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz

题解
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
      ListNode* qwe=new  ListNode(0);
      qwe->next=head;
      ListNode *p=qwe;                                   
      ListNode *q=qwe;
      for(int i=0;inext;
      }
      while(p!=NULL)
      {
          q=q->next;
          p=p->next;
      }
        ListNode* delNode = q->next;
        q->next = delNode->next;
        delete delNode;
        ListNode* retNode = qwe->next;
        delete qwe;
        return retNode;

    }
};
面试题 02.02. 返回倒数第 k 个节点

实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。

注意:本题相对原题稍作改动

示例:

输入: 1->2->3->4->5 和 k = 2
输出: 4
说明:

给定的 k 保证是有效的。

题解
class Solution {
public:
    int kthToLast(ListNode* head, int k) {
        ListNode * qwe = new ListNode(0);
        qwe->next=head;
        ListNode * q=qwe;
        ListNode * w=qwe;
      for(int i=0;inext;
      }
      while(w)
      {
          w=w->next;
          q=q->next;
      }
      return q->next->val;


    }
};
面试题 02.04. 分割链表

给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。

你不需要 保留 每个分区中各节点的初始相对位置。

示例 1:

输入:head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]

题解
class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        ListNode* small=new ListNode(0);
         ListNode* large=new ListNode(0);
         ListNode* smallhead=small;
         ListNode* largehead=large;
         while(head)
         {
             if(head->val>=x)
                 {large->next=head; large=large->next;}
             if(head->valnext=head; small=small->next;}
                 head=head->next;
         }
         large->next = nullptr;
         small->next = largehead->next;
         return smallhead->next;
    }
};
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/384784.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号