1、有效括号
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。
class Solution{
public:
bool isValid(string s) {
int len = s.size();
if(len % 2 == 1) return false;
unordered_map<char, int> map{{'(', 1}, {'[', 2}, {'{', 3}, {')', 4}, {']', 5}, {'}', 6}};
stack<char> stack;
for(char c : s){
int flag = map[c];
if(flag >= 1 && flag <= 3)
stack.push(c);
else if(!stack.empty() && flag - 3 == map[stack.top()])
stack.pop();
else return false;
}
if(!stack.empty()) return false;
return true;
}
};
2、环形链表
给定一个链表,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true 。 否则,返回 false 。
class Solution {
public:
bool hasCycle(ListNode *head) {
ListNode *slow = head;
ListNode *fast = head;
while(fast && fast->next){
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
return true;
}
return false;
}
};
3、全排列
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
class Solution {
public:
vector<vector<int>> res;
vector<int> tmp;
bool st[6];
void dfs(vector<int> &nums, int k){
if(nums.size() == tmp.size()){
res.push_back(tmp);
return;
}
for(int i = 0; i < nums.size(); i++){
if(!st[i]){
st[i] = true;
tmp.push_back(nums[i]);
dfs(nums, k + 1);
tmp.pop_back();
st[i] = false;
}
}
}
vector<vector<int>> permute(vector<int>& nums) {
dfs(nums, 0);
return res;
}
};
4、相交链表
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *l1 = headA;
ListNode *l2 = headB;
while(l1 != l2){
l1 = l1 != nullptr ? l1->next : headB;
l2 = l2 != nullptr ? l2->next : headA;
}
return l1;
}
};
5、组合总和
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
class Solution {
public:
vector<vector<int>> res;
vector<int> tmp;
void dfs(vector<int> &candidates, vector<vector<int>> &res, vector<int> &tmp, int target, int index){
if(target == 0)
res.push_back(tmp);
if(index >= candidates.size()) return;
if(target < candidates[index]) return;
for(int i = index; i < candidates.size(); i++){
tmp.push_back(candidates[i]);
dfs(candidates, res, tmp, target - candidates[i], i);
tmp.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
sort(candidates.begin(), candidates.end());
dfs(candidates, res, tmp, target, 0);
return res;
}
};
6、手撕快速排序
给你一个整数数组 nums,请你将该数组升序排列。
class Solution {
public:
int partition(vector<int> &nums, int l, int r, int mid){
int tmp = nums[mid];
nums[mid] = nums[l];
while(l < r){
while(l < r && nums[r] >= tmp)
r--;
nums[l] = nums[r];
while(l < r && nums[l] <= tmp)
l++;
nums[r] = nums[l];
}
nums[l] = tmp;
return l;
}
void quicksort(vector<int> &nums, int l, int r){
if(l < r){
int mid = l + rand() % (r - l + 1);
mid = partition(nums, l, r, mid);
quicksort(nums, l, mid - 1);
quicksort(nums, mid + 1, r);
}
}
vector<int> sortArray(vector<int>& nums) {
int n = nums.size();
quicksort(nums, 0, n - 1);
return nums;
}
};
7、缺失的数字
给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。
class Solution {
public:
int missingNumber(vector<int>& nums) {
int sum = 0;
int aclsum = 0;
for(int i = 0; i <= nums.size(); i++){
sum += i;
}
for(int num : nums){
aclsum += num;
}
return sum - aclsum;
}
};
8、环形链表-2
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *slow = head;
ListNode *fast = head;
while(fast && fast->next){
fast = fast->next->next;
slow = slow->next;
if(slow == fast){
ListNode *ptr = head;
while(ptr != slow){
slow = slow->next;
ptr = ptr->next;
}
return ptr;
}
}
return nullptr;
}
};
9、分隔链表
给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。
你应当 保留 两个分区中每个节点的初始相对位置。
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
ListNode* small = new ListNode(0);
ListNode* smallHead = small;
ListNode* large = new ListNode(0);
ListNode* largeHead = large;
while(head){
if(head->val < x){
small->next = head;
small = small->next;
}
else{
large->next = head;
large = large->next;
}
head = head->next;
}
large->next = nullptr;
small->next = largeHead->next;
return smallHead->next;
}
};
10、最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
class Solution {
public:
int getsub(int l, int r, string s){
while(l >= 0 && r < s.size() && s[l] == s[r]){
l--;
r++;
}
return r - l - 1;
}
string longestPalindrome(string s) {
int start = 0, len = 0;
for(int i = 0; i < s.size(); i++){
int tmp = max(getsub(i, i, s), getsub(i, i + 1, s));
if(tmp > len){
len = tmp;
start = i - (len - 1) / 2;
}
}
return s.substr(start, len);
}
};