记录贴,只为了统一完美格式
文章目录
双指针
167. 两数之和 II - 输入有序数组
时间复杂度:O(n)
空间复杂度:O(1)
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
int l = 0, r = numbers.size()-1;
while (l < r) {
int sum = numbers[l] + numbers[r];
if (sum == target) break;
if (sum < target) l++;
else r--;
}
return vector<int> {l+1, r+1};
}
};
88. 合并两个有序数组
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int pos = m + n - 1;
m--;
n--;
while (m >= 0 && n >= 0) {
if (nums1[m] >= nums2[n]) {
swap(nums1[pos--], nums1[m--]);
}
else {
swap(nums1[pos--], nums2[n--]);
}
}
while (n>=0) {
swap(nums1[pos--], nums2[n--]);
}
}
};
贪心算法
455.分发饼干
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(), g.end());
sort(s.begin(), s.end());
int i = 0, j = 0;
while (i<g.size() && j < s.size()) {
if (g[i] <= s[j]) i++;
j++;
}
return i;
}
};
135. 分发糖果
class Solution {
public:
int candy(vector<int>& ratings) {
if (ratings.size() <= 1) {
return ratings.size();
}
vector<int> res(ratings.size(), 1);
for (int i = 1; i < ratings.size(); ++i) {
if (ratings[i] > ratings[i-1]) res[i] = res[i-1] + 1;
}
for (int i = ratings.size()-1; i > 0; --i) {
if (ratings[i] < ratings[i-1]) res[i-1] = max(res[i-1], res[i]+1);
}
return accumulate(res.begin(), res.end(), 0);
}
};
435. 无重叠区间
时间复杂度:O(nlogn)
空间复杂度:O(logn)
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
if (intervals.empty()) {
return 0;
}
// 必须& 不然报超时
sort(intervals.begin(), intervals.end(), [](const auto &a, const auto &b) {
return a[1] < b[1];
});
int res = 0, right = intervals[0][1], n = intervals.size();
for (int i = 1; i < n; ++i) {
if (intervals[i][0] < right) ++res;
else right = intervals[i][1];
}
return res;
}
};
605. 种花问题
自己为空
左边为空 或者 自己是最左
右边为空 或者 自己是最右
时间复杂度:O(m),其中 m 是flowerbed 的长度
空间复杂度:O(1)O(1)。额外使用的空间为常数。
class Solution {
public:
bool canPlaceFlowers(vector<int>& flowerbed, int n) {
int l = flowerbed.size();
for (int i = 0; i<flowerbed.size(); i++) {
if (flowerbed[i] == 0 && (i ==0 || flowerbed[i-1] == 0 ) && (i == l-1 || flowerbed[i+1] == 0 )) {
n--;
if (n <= 0) return true;
flowerbed[i] = 1;
}
}
return n <= 0;
}
};
452. 用最少数量的箭引爆气球
时间复杂度:O(nlogn)
空间复杂度:O(logn)
class Solution {
public:
int findMinArrowShots(vector<vector<int>>& points) {
sort(points.begin(), points.end(), [](vector<int>&a, vector<int>&b) {
return a[1] < b[1];
});
int prev = points[0][1], res = 1;
for (int i = 1; i < points.size(); i++) {
if (points[i][0] > prev) {
res ++;
prev = points[i][1];
}
}
return res;
}
};
763. 划分字母区间
时间复杂度:O(n)
空间复杂度:O(26)
class Solution {
public:
vector<int> partitionLabels(string s) {
vector<int> last_pos(26, 0);
for (int i = 0; i < s.size(); i++) {
last_pos[s[i]-'a'] = i;
}
int start = 0, end = 0;
vector<int> res;
for (int i = 0; i < s.size(); i++) {
end = max(end, last_pos[s[i] - 'a']);
if (i == end) {
res.emplace_back(end-start+1);
start = end + 1;
}
}
return res;
}
};
122. 买卖股票的最佳时机 II
时间复杂度:O(n)
空间复杂度:O(1)
class Solution {
public:
int maxProfit(vector<int>& prices) {
int res = 0;
for (int i = 0; i < prices.size()-1; i++) {
res += max(0, prices[i+1] - prices[i]);
}
return res;
}
};
406. 根据身高重建队列
候选从高到低排,然后插空
时间复杂度:O(n^2)
空间复杂度:O(logn)
class Solution {
public:
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
sort(people.begin(), people.end(), [](vector<int> &a, vector<int> &b){
return (a[0] > b[0] || (a[0] == b[0] && a[1] < b[1]));
});
vector<vector<int>> res;
for (auto &p : people) {
res.insert(res.begin()+p[1], p);
}
return res;
}
};
665. 非递减数列
class Solution {
public:
bool checkPossibility(vector<int>& nums) {
if (nums.size() == 1) return true;
bool flag = nums[0] <= nums[1] ? true:false;
for (int i = 1; i < nums.size()-1; i++) {
if (nums[i] > nums[i+1]) {
if (flag) {
if (nums[i+1] >= nums[i-1]) nums[i] = nums[i+1];
else nums[i+1] = nums[i];
flag = false;
}
else return false;
}
}
return true;
}
};
随缘刷
1.两数之和
解法:hash表
class Solution {
public:
vector<int> twoSum(vector<int> &nums, int &target) {
unordered_map<int,int> hashtabel;
for (int i = 0; i < nums.size(); ++i) {
auto it = hashtabel.find(target-nums[i]);
if (it != hashtabel.end()){
return {it->second, i};
}
hashtabel[nums[i]] = i;
}
return {};
}
};
2.两数相加
解法:链表
/**
* 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 * addTwoNumbers(ListNode *l1, ListNode *l2){
ListNode *head = nullptr, *tail = nullptr;
int carry = 0;
while (l1 || l2) {
int n1 = l1 ? l1->val : 0;
int n2 = l2 ? l2->val : 0;
int sum = n1 + n2 + carry;
if (!head) {
head = tail = new ListNode(sum%10);
}
else {
tail->next = new ListNode(sum%10);
tail = tail->next;
}
carry = sum / 10;
if (l1) l1 = l1->next;
if (l2) l2 = l2->next;
}
if (carry > 0) {
tail->next = new ListNode(carry);
}
return head;
}
};
3.无重复字符的最长子串
解法:滑动窗口
时间复杂度:O(N)
空间复杂度:O(∣Σ∣),其中 Σ 表示字符集(即字符串中可以出现的字符),∣Σ∣ 表示字符集的大小。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_set<char> occor;
int right = 0, left = 0, max_len = 0;
while (left < s.size()) {
while (right < s.size() && !occor.count(s[right])) {
occor.insert(s[right]);
right ++;
}
max_len = max(max_len, right-left);
occor.erase(s[left]);
left ++ ;
}
return max_len;
}
};
4.寻找两个正序数组的中位数
策略:二分法
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int m = nums1.size();
int n = nums2.size();
int left = (m+n+1) / 2;
int right = (m+n+2) / 2;
return (getKth(nums1, 0 ,m-1, nums2, 0, n-1, left) + getKth(nums1, 0 ,m-1, nums2, 0, n-1, right)) / 2;
}
double getKth(vector<int> &nums1, int start1, int end1, vector<int> &nums2, int start2, int end2, int k) {
int len1 = end1 - start1 + 1;
int len2 = end2 - start2 + 1;
if (len1 > len2) {
return getKth(nums2, start2, end2, nums1, start1, end1, k);
}
// nums1 is null
if (len1 == 0) {
return nums2[start2+k-1];
}
if (k==1) {
return min(nums1[start1], nums2[start2]);
}
int i = start1 + min(len1, k/2) - 1;
int j = start2 + min(len2, k/2) - 1;
if (nums1[i] <= nums2[j]) {
return getKth(nums1, i+1, end1, nums2, start2, end2, k-(i-start1+1));
}
else {
return getKth(nums1, start1, end1, nums2, j+1, end2, k-(j-start2+1));
}
}
};
4.最长回文子串
class Solution {
public:
string longestPalindrome(string s) {
int n = s.size();
if (n < 2) {
return s;
}
int max_len = 1;
int begin = 0;
vector<vector<int>> dp(n, vector<int>(n));
// init
for (int i = 0; i< n; i++) {
dp[i][i] = true;
}
// 递归开始
for (int lenght = 2; lenght <= n; lenght++) {
for (int i = 0; i < n; i++) {
int j = lenght+i-1;
if (j >= n) break;
if (s[i] != s[j]) {
dp[i][j] = false;
}
else {
if (j-i<3) {
dp[i][j] = true;
}
else dp[i][j] = dp[i+1][j-1];
}
if (dp[i][j] && j-i+1 > max_len) {
max_len = j-i+1;
begin = i;
}
}
}
return s.substr(begin, max_len);
}
};