双指针类
有序数组的 Two Sum
leetcode.0167. Two Sum II - Input array is sorted
Input: numbers = [2,7,11,15], target = 9
Output: [1,2]
Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.
题目描述:在有序数组中找出两个数,使它们的和为 target。
使用双指针,一个指针指向值较小的元素,一个指针指向值较大的元素。指向较小元素的指针从头向尾遍历,指向较大元素的指针从尾向头遍历。
如果两个指针指向元素的和 sum == target,那么得到要求的结果;
如果 sum > target,移动较大的元素,使 sum 变小一些;
如果 sum < target,移动较小的元素,使 sum 变大一些。
C++
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
int i = 0, j = numbers.size()-1;
while (i<j) {
int sum = numbers[i] + numbers[j];
if (sum == target){
return {i+1, j+1};
}
else if (sum < target){
i++;
}
else {
j--;
}
}
return {0,0};
}
};
python
class Solution:
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
'''
思路
利用两个指针从数组的两侧开始向中间移动,寻找第一对和为target的两个数即为所求
'''
left, right = 0, len(numbers) - 1
while left < right:
if numbers[left] + numbers[right] == target:
return [left + 1, right + 1]
elif numbers[left] + numbers[right] > target:
right -= 1
else:
left += 1
两数平方和
leetcode.0633. Sum of Square Numbers
Input: 5
Output: True
Explanation: 1 * 1 + 2 * 2 = 5
题目描述:判断一个数是否为两个数的平方和,例如 5 = 1^2 + 2^2。
class Solution {
public:
bool judgeSquareSum(int c) {
int i = 0, j = int(sqrt(c));/*与python区别*/
while (i<=j) {
int powSum = i*i + j*j;
if (powSum == c) {
return true;
}
else if (powSum > c) {
j--;
}
else {
i++;
}
}
return false;
}
};
反转字符串中的元音字符
leetcode.0345. Reverse Vowels of a String
Given s = "leetcode", return "leotcede".
使用双指针,指向待反转的两个元音字符,一个指针从头向尾遍历,一个指针从尾到头遍历。
class Solution {
public:
string reverseVowels(string s) {
int i = 0, j = s.size() - 1;
while (i < j) {
if (!isVowel(s[i])) {
i++;
}
else if (!isVowel(s[j])) {
j--;
}
else {
swap(s[i],s[j]);
i++;
j--;
}
}
return s;
}
bool isVowel(char c)
{
if((c=='a')||(c=='e')||(c=='i')||(c=='o')||(c=='u')||(c=='A')||(c=='E')||(c=='I')||(c=='O')||(c=='U'))
return true;
return false;
}
};
回文字符串
leetcode.0680. Valid Palindrome II
Input: "abca"
Output: True
Explanation: You could delete the character 'c'.
题目描述:可以删除一个字符,判断是否能构成回文字符串。
class Solution {
public:
bool validPalindrome(string s) {
int i = 0, j = s.size() - 1;
while (i < j) {
if (s[i] != s[j]) {
return isPalindrome(s, i, j - 1) || isPalindrome(s, i + 1, j);
}
i++;
j--;
}
return true;
}
private:
bool isPalindrome(string s, int i, int j) {
while (i < j) {
if (s[i] != s[j] ) {
return false;
}
i++;
j--;
}
return true;
}
};
归并两个有序数组
leetcode.0088. Merge Sorted Array
Input:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
Output: [1,2,2,3,5,6]
题目描述:把归并结果存到第一个数组上。
需要从尾开始遍历,否则在 nums1 上归并得到的值会覆盖还未进行归并比较的值。
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int index1 = m - 1, index2 = n - 1;
int indexMerge = m + n - 1;
while (index1 >= 0 || index2 >= 0) {
if (index1 < 0) {
nums1[indexMerge] = nums2[index2];
indexMerge--;
index2--;
}
else if (index2 < 0) {
nums1[indexMerge] = nums1[index1];
indexMerge--;
index1--;
}
else if (nums1[index1] > nums2[index2]) {
nums1[indexMerge] = nums1[index1];
indexMerge--;
index1--;
}
else {
nums1[indexMerge] = nums2[index2];
indexMerge--;
index2--;
}
}
}
};
判断链表是否存在环
leetcode.0141. Linked List Cycle
使用双指针,一个指针每次移动一个节点,一个指针每次移动两个节点,如果存在环,那么这两个指针一定会相遇。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
if (!head || !head->next) {
return false;
}
ListNode *l1 = head, *l2 = head->next;
while (l1 != NULL && l2 != NULL && l2->next != NULL) {
if (l1 == l2) {
return true;
}
l1 = l1->next;
l2 = l2->next->next;
}
return false;
}
};
最长子序列
leetcode.0524. Longest Word in Dictionary through Deleting
Input:
s = "abpcplea", d = ["ale","apple","monkey","plea"]
Output:
"apple"
题目描述:删除 s 中的一些字符,使得它构成字符串列表 d 中的一个字符串,找出能构成的最长字符串。如果有多个相同长度的结果,返回字典中的顺序的最小字符串。
class Solution {
public:
string findLongestWord(string s, vector<string>& d) {
string LongestWord = "";
for (string target : d) {
int l1 = LongestWord.size(), l2 = target.size();
if ((l1 > l2) || (l1 == l2 && LongestWord.compare(target) < 0)) {
continue;
}
if (isValid(s, target)) {
LongestWord = target;
}
}
return LongestWord;
}
private:
bool isValid(string s, string target) {
int i = 0, j = 0;
while (i < s.size() && j < target.size()) {
if (s[i] == target[j]) {
j++;
}
i++;
}
return j == target.size();
}
};
参考
https://github.com/CyC2018/CS-Notes/blob/master/notes/Leetcode%20%E9%A2%98%E8%A7%A3.md