算法——雙指針算法

雙指針算法

​ 雙指針算法是指一切採用雙指針的方式,降低原本暴力解法的時間複雜度的算法,通常雙指針算法可以將暴力的 O(n^2)降低到 O(n)

​ 由於雙指針算法指的是一類算法,下面我用兩道題來簡單解釋一下

單詞個數問題

​ 即查找一段字符串中,以空格爲分隔的單詞的個數,這道題用暴力法完全可解,外層 for 循環遍歷整個字符數組,內層 for 循環檢測 ' ' 字符,但是顯然這種方法時間複雜度是 O(n^2)

​ 如果採用雙指針算法, 外層循環用來控制遍歷字符串,內層循環直接跳到 ' ' 處,記住這個單詞後,直接將外層循環跳到 ' ' 的下一位繼續執行,時間複雜度便爲 'O(n)'

代碼

#include <iostream>
#include <string>

using namespace std;

int numStr(char str[]) {
	int sum = 0;
	int l = 0, r = 0;
	int length = strlen(str);
	while (str[l]) {
		while (r <= length && str[r] != ' ')
			r++;
		for (int k = l; k < r; k++)
			cout << str[k];
		cout << endl;
		sum++;
		l = ++r;
	}
	return sum;
}

int main() {
	int sum = numStr("hello world !");
	cout << "有 " << sum << " 個單詞" << endl;
	return 0;
}

最長連續不重複子序列問題

​ 首先,這個問題也可以使用暴力法,嵌套 for 循環,可以解決問題,但是速度慢且代碼複雜

​ 採用雙指針算法的思想,第一個指針持續後移,使用另一個數組統計每個數字出現的次數來控制第二個指針的移動,以此來計算不重複子序列,時間複雜度可達到 O(n)

代碼

#include <iostream>
#include <Windows.h>

using namespace std;

const int N = 100010;

int a[N];
int s[N];
int n;

int main() {
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> a[i];
	int res = 0;
	for (int i = 0, j = 0; i < n; i++) {
		s[a[i]]++;
		while (s[a[i]] > 1) {
			s[a[j]]--;
			j++;
		}
		res = max(res, i - j + 1);
	}
	cout << res << endl;	
	return 0;
}

歸併排序

​ 另外歸併排序也是雙指針算法的一個實例,歸併排序在我之前的博客有講過,鏈接是:歸併排序講解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章