10. 正则表达式匹配
题目
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。
‘.’ 匹配任意单个字符
‘*’ 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
示例 1:
输入:s = “aa” p = “a”
输出:false
解释:“a” 无法匹配 “aa” 整个字符串。
示例 2:
输入:s = “aa” p = “a*”
输出:true
解释:因为 ‘*’ 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 ‘a’。因此,字符串 “aa” 可被视为 ‘a’ 重复了一次。
示例 3:
输入:s = “ab” p = “."
输出:true
解释:".” 表示可匹配零个或多个(’*’)任意字符(’.’)。
示例 4:
输入:s = “aab” p = “cab”
输出:true
解释:因为 ‘*’ 表示零个或多个,这里 ‘c’ 为 0 个, ‘a’ 被重复一次。因此可以匹配字符串 “aab”。
示例 5:
输入:s = “mississippi” p = “misisp*.”
输出:false
11. 盛最多水的容器
题目
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
图中垂直线代表输入数组 [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<int>& height) {
int left = 0, right = height.size()-1;
int ans = 0;
while (left < right) {
int temp = min(height[left], height[right]) * (right - left);
if (temp > ans) {
ans = temp;
}
if (height[left] < height[right]) {
left++;
}
else {
right--;
}
}
return ans;
}
};
17. 电话号码的字母组合
题目
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:“23”
输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].
解答
采用回溯法
class Solution{
public:
vector<string> letterCombinations(string digits) {
vector<string> ans;
if (digits.size() == 0) {
return ans;
}
string lans;
lc(ans,lans,phoneMap,digits,0);
return ans;
}
private:
unordered_map<char,string> phoneMap{
{'2',"abc"},
{'3',"def"},
{'4',"ghi"},
{'5',"jkl"},
{'6',"mno"},
{'7',"pqrs"},
{'8',"tuv"},
{'9',"wxyz"}
};
void lc(vector<string> &ans,string &lans,unordered_map<char,string> phoneMap,string digits,int index) {
if (index == digits.length()) {
ans.push_back(lans);
}else {
char digit = digits[index];
string letters = phoneMap.at(digit);
for (auto letter : letters) {
lans.push_back(letter);
lc(ans,lans,phoneMap,digits,index + 1);
lans.pop_back();
}
}
}
};
19. 删除链表的倒数第N个节点
题目
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
解答
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* ps = new ListNode(0,head);
ListNode* p1 = ps;
for(int i = 0;i < n + 1 ;i++){
p1 = p1->next;
}
ListNode* p2 = ps;
while(p1 != nullptr){
p1 = p1->next;
p2 = p2->next;
}
ListNode* p3 = p2->next;
if(p2->next != nullptr){
p2->next = p2->next->next;
}else{
p2->next = nullptr;
}
delete p3;
return ps->next;
}
};