双指针经典练习:

  • 双指针经典练习:

1 :题目大意 : 输入一个数组 , 求子序列的个数(子序列连续并且不包含重复元素)(题目链接
Input : 5 1 1 2 1 5
Output : 9
样例解释 :子序列有 (1)(1)(1,2)(2)(2,1)(2,1,5)(1)(1,5)(5)

解题思路1 :
1 :设置一个集合记录不重复元素序列的个数

2 :ans += 集合中的值的大小

3: 用 i 指针来记录答案 ,j 指针始终使集合中不出现重复元素

  • AC代码1:
#include<bits/stdc++.h>
using namespace std;
#define int long long 
const int N = 1e5 + 99 ;
signed main()
{
         int n , a[N] , ans = 0 ;
         set<int> s ;
         cin >> n ;
         for( int i = 1 ; i <= n ; i ++ )
         {
             cin >> a[i] ;
         }
         int i = 1 , j = 1 ;
         while( i <= n )
         {
              while( !s.count(a[i]) && i <= n )
              {
                  s.insert(a[i]) ;
                  ans += s.size( ) ;
                  i ++ ;
              }
              while( s.count(a[i]) && j <= n )
              {
                   s.erase(a[j]) ;
                   j ++ ;
              }
         }
         cout << ans ;
     return 0 ;
}

解题思路2 :
1 : 用一个队列记录不重复子序列 , 这个队列就用数组本身

2 : ans += 队列中的个数

3 : 队列始终保持不重复出现元素

  • AC代码2:
#include<bits/stdc++.h>
using namespace std;
#define int long long 
const int N = 1e5 + 99 ;
int a[N] , n , ans = 0 , fro = 0  ;
map < int ,int > vis ;
signed main()
{
       cin >> n ;
       for( int i = 1 ; i <= n ; i ++ )
       {
            cin >> a[i] ;
            vis[a[i]] ++ ;
            while( vis[a[i]] > 1 )
            {
                vis[a[++fro]] --  ;
            }
            ans += i - fro ;
       }
       cout << ans  ; 
       return 0 ;
}

总结,看似是两种思路 , 实际上它的核心思想: 双指针解法
用一个指针记录答案,另外一个指针维护这个没有重复元素的最长子序列。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值