LeetCode 167. Two Sum II - Input arrray is sorted (Easy)
分析:设置left,right两个指针,分别指向数组的最左边和最右边元素。while循环,循环条件为left LeetCode 633. Sum of Square Numbers (Easy) 本题与问题1具有相同计算流程,区别在于target变为了两数平方和。 Note:这里可以将right直接初始化为 c \sqrt {c} c。根据根号大小的性质可以减少不必要的操作。 LeetCode 345. Reverse Vowels of a String (Easy) 依然使用的是双指针从两边到中间的收缩过程。当left和right都指向一个元音字符的时候进行交换操作即可。 LeetCode 680. Valid Palindrome II (Easy) 双指针判断回文串实现非常简单。本题是删除最多一个元素能否形成回文串。那么如果本身就是回文串,不需要进行删除操作,直接返回True即可。当判断过程中遇见不是回文的情况,需要作出如下判断。 有串如: 当left指向b,right指向d的时候,while循环第一次遇见不相等的情况,此时只需要判断 LeetCode 88. Merge Sorted Array (Easy) 本题思路交简单,但是两种实现方法时间复杂度不一样 方法一:(时间复杂度 O ( n 2 ) O(n^2) O(n2)) 类似于归并两个链表的操作,从前往后依次把nums2中的数,插入到nums1中去。这里需要注意,每次插入数据,后面的数据都要向后移动一位。这样造成一个双重循环。(由于链表每次修改数据,不需要修改后面的数据,所以时间复杂度为 O ( 1 ) O(1) O(1),但是数组需要后面每一位都修改,因此这样归并的时间消耗大大增加。) 方法二:(时间复杂度 O ( m + n ) O(m+n) O(m+n)) 如果从后向前归并数据,两个指针分别指向nums1和nums2的末尾m-1, n-1处,他们的结果比较大小,最后归并到nums1的m+n-1处,每次归并,并不需要修改其他的数据。 LeetCode 141. Linked List Cycle (Easy) 思路:如果一个链表有环,遍历链表一定无法退出这个环。设置两个指针,一个快(每次走两步)一个慢(每次走一步),那么这两个指针一定会相遇。如果两个指针都走到了终点,那么该链表一定没有环。 LeetCode 524. Longest Word in Dictionary through Deleting (Medium) 分析:本题看似繁琐,思路其实很清晰。 如果a字符串删除部分字符可以得到b字符串,那么可以理解为b是a的一个“带限制条件的子串”。设置两个指针i, j分别指向a的0索引出和b的0索引处。while循环遍历两个字符串,循环结束时,如果j的大小刚好为b串的长度,那么符合题目条件。 这时候,判断b串的长度以及字典序是不是最长,最小即可。(字典序:按照字符串每个字符的大小进行比较)# Python
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
left, right = 0, len(numbers)-1
while left < right:
tmp = numbers[left] + numbers[right]
if tmp < target:
left += 1
elif tmp > target:
right -= 1
else:
res = [left+1, right+1]
break
return res
# c++
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
int left = 0, right = numbers.size()-1;
vector<int> ret;
while (left < right) {
int sum = numbers[left] + numbers[right];
if (sum < target)
left++;
else if (sum > target)
right--;
else {
ret.push_back(++left);
ret.push_back(++right);
break;
}
}
return ret;
}
};
2. 两个整数的平方和
# Python
class Solution:
def judgeSquareSum(self, c: int) -> bool:
left, right = 0, int(math.sqrt(c))
while left <= right:
if left * left + right * right < c:
left += 1
elif left * left + right * right > c:
right -= 1
else:
return True
return False
# C++
class Solution {
public:
bool judgeSquareSum(int c) {
long int left = 0, right = sqrt(c);
while (left <= right) {
if (left * left + right * right < c)
left++;
else if (left * left + right * right > c)
right--;
else {
return true;
}
}
return false;
}
};
3. 翻转字符串中的元音字符
# Python
class Solution:
def reverseVowels(self, s: str) -> str:
left, right = 0, len(s)-1
mySet = ('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U')
res = list(s)
while left < right:
if not res[left] in mySet:
left += 1
if not res[right] in mySet:
right -= 1
if res[left] in mySet and res[right] in mySet:
tmp = res[left]
res[left] = res[right]
res[right] = tmp
left += 1
right -= 1
return ''.join(res)
# C++
# 目前对C++的STL还不是很熟悉,这可能不是最好的方法。还有一种思路是直接使用数组存储,判断
# 的时候只要判断字符ASCII值对应索引即可。
class Solution {
public:
string reverseVowels(string s) {
int left = 0, right = s.size()-1;
map<char, char> myMap = {{'a', 1}, {'e', 1}, {'i', 1}, {'o', 1}, {'u', 1}, {'A', 1}, {'E', 1}, {'I', 1}, {'O', 1}, {'U', 1}};
while (left < right) {
map<char, char>::iterator findLeft = myMap.find(s[left]);
map<char, char>::iterator findRight = myMap.find(s[right]);
if (findLeft == myMap.end())
left++;
if (findRight == myMap.end())
right--;
if (findLeft != myMap.end() && findRight != myMap.end()) {
char tmp = s[left];
s[left] = s[right];
s[right] = tmp;
left++;
right--;
}
}
return s;
}
};
4. 回文字符串
[a, b, c, d, a]
[b, c]
和[c, d]
两个子串,是不是回文串,即可,如果是,那么删除其中一个字符剩下的字符就是回文串,如果两个都不是回文串,那么整个字符串仅仅删除一个字符不可能构成回文串。# Python
class Solution:
def validPalindrome(self, s: str) -> bool:
left, right, count = 0, len(s)-1, 0
while left < right:
if s[left] == s[right]:
left += 1
right -= 1
else:
return (self.isPalindrome(s[left:right]) or
self.isPalindrome(s[left+1:right+1]))
return True
def isPalindrome(self, s):
left, right = 0, len(s)-1
while left < right:
if s[left] == s[right]:
left += 1
right -= 1
else:
return False
return True
# C++
class Solution {
public:
bool validPalindrome(string s) {
int left = 0, right = s.size() - 1;
while (left < right) {
if (s[left] == s[right]) {
left++;
right--;
} else
return (isPalindrome(s.substr(left, right-left)) ||
isPalindrome(s.substr(left+1, right-left)));
}
return true;
}
bool isPalindrome(string s) {
int left = 0, right = s.size() - 1;
while (left < right) {
if (s[left] == s[right]) {
left++;
right--;
} else
return false;
}
return true;
}
};
5. 归并两个有序数组
# Python
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
up, middle, down = m - 1, m + n - 1 ,n - 1
while up >= 0 and down >= 0:
if nums1[up] >= nums2[down]:
nums1[middle] = nums1[up]
up -= 1
middle -= 1
else:
nums1[middle] = nums2[down]
down -= 1
middle -= 1
while down >= 0:
nums1[middle] = nums2[down]
down -= 1
middle -= 1
# C++
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int up = m - 1, down = n - 1, middle = m + n - 1;
while (up >= 0 && down >= 0) {
if (nums1[up] >= nums2[down]) {
nums1[middle] = nums1[up];
up--;
middle--;
} else {
nums1[middle] = nums2[down];
down--;
middle--;
}
}
while (down >= 0) {
nums1[middle] = nums2[down];
down--;
middle--;
}
}
};
6. 判断链表是否存在环
# Python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: ListNode) -> bool:
if not head: return False
slow, fast = head, head.next
while slow and fast and fast.next:
if slow == fast:
return True
else:
slow = slow.next
fast = fast.next.next
return False
# C++
/**
* 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) return false;
ListNode *slow = head, *fast = head -> next;
while (slow && fast && fast -> next) {
if (slow == fast)
return true;
slow = slow -> next;
fast = fast -> next -> next;
}
return false;
}
};
7. 带限制条件的最长子序列
# Python
class Solution:
def findLongestWord(self, s: str, d: List[str]) -> str:
res = ''
for subs in d:
if len(res) > len(subs): continue
i, j = 0, 0
while i < len(s) and j < len(subs):
if s[i] == subs[j]:
i += 1
j += 1
else:
i += 1
if j == len(subs):
if len(subs) > len(res):
res = subs
if len(subs) == len(res):
if subs < res:
res = subs
return res
# C++
//留坑