581. 最短无序连续子数组
我也是很疑惑为什么有那么多做法,自己一个也没想起来
题解思路1
使用sort,第一个和原数组不一样的元素的下标为左值,最后一个为右值。
vector<int> vec(nums);
sort(vec.begin(), vec.end());
int left = nums.size() - 1, right = 0;
for (int i = 0; i < nums.size(); ++i) {
if (nums[i] != vec[i]) {
left = min(left, i);
right = max(right, i);
}
}
return right - left > 0 ? right - left + 1 : 0;
需要注意的地方。vector的拷贝均为深拷贝,重载了=
运算符
题解思路2 :超时
在边界[i, j]中,如果存在有数比nums[i]小,则left = i,如果有数比nums[j]大,则right = j;
n^2遍历
for (int i = 0; i < nums.size(); ++i) {
for (int j = i + 1; j < nums.size(); ++j)
//如果只是找左边界,碰到第一个num[j] < nums[i],left赋值之后就可以return了
if (nums[j] < nums[i]) {
left = min(left, i);
right = max(right, j);
}
}
我的思路
按照上面的思路我把左右分开,没有超时(也接近超时了)
for (int i = 0; i < nums.size() && flag; ++i) {
for (int j = i + 1; j < nums.size(); ++j)
//如果只是找左边界,碰到第一个num[j] < nums[i],left赋值之后就可以return了
if (nums[j] < nums[i]) {
left = min(left, i);
flag = false;
break;
}
}
flag = true;
for (int i = nums.size() - 1; i >= 0 && flag; --i) {
for (int j = i - 1; j >= 0; --j)
if (nums[j] > nums[i]) {
right = max(right, i);
flag = false;
break;
}
}
题解思路3
再延伸一下上面的思路,找到逆序对中最小的值和最大的值,从左往右第一个大于min的下标为left,从右往左第一个大于max的下标为right
int left = nums.size() - 1, right = 0;
if (nums.size() <= 1) return 0;
int maxnum = INT_MIN, minnum = INT_MAX;
for (int i = 1; i < nums.size(); ++i) {
if (nums[i - 1] > nums[i]) {
minnum = min(minnum, nums[i]);
maxnum = max(maxnum, nums[i - 1]);
}
}
for (left = 0; left < nums.size(); ++left) {
if (nums[left] > minnum) break;
}
for (right = nums.size() - 1; right >= 0; --right) {
if (nums[right] < maxnum) break;
}
return left > right ? 0 : right - left + 1;
617. 合并二叉树
题解思路
尽量少对下一层做判断,我在root1left连接到root2的left上后,对root2 -> left的释放上纠结了很长时间
因为是到底再回溯的,所以不用释放对后面也没有影响,就是这个节点会同时被root1和root2所指.还是新开一个root吧
if (!root2 && !root1) return nullptr;
if (!root1) return root2;
if (!root2) return root1;
// TreeNode* root = new TreeNode(root1 -> val + root2 -> val);
root1 -> val += root2 -> val;
root1 -> left = mergeTrees(root1 -> left, root2 -> left);
root1 -> right = mergeTrees(root1 -> right, root2 -> right);
return root1;
621. 任务调度器
题解思路
先把最长的排好,取左边这种情况和右边这种情况的最大值
vector<int> chcnt(26, 0);
int maxchcnt = 0;
for (char c : tasks) {
chcnt[c - 'A'] += 1;
maxchcnt = max(maxchcnt, chcnt[c - 'A']);
}
int maxcount = 0;
for (int t : chcnt) {
if (t == maxchcnt) {
maxcount++;
}
}
int size = tasks.size();
return max((n + 1) * (maxchcnt - 1) + maxcount, size);
647. 回文子串
题解思路
我不知道怎么处理回文串的中心位置,思路应该是确定一个中心位置,像两边扩散如果字符相等,ans++
int len = s.size();
int ans = 0;
for (int i = 0; i < len * 2 - 1; ++i) {
int left = i / 2, right = i / 2 + i % 2;
while (left >= 0 && right <= len - 1 && s[left] == s[right]) {
left--;
right++;
ans++;
}
}
return ans;
739. 每日温度
我的思路
逆序单调栈,没什么毛病的bug-free
stack<int> st;
vector<int> ans(T.size(), 0);
for (int i = T.size() - 1; i >= 0; --i) {
while (!st.empty() && T[i] >= T[st.top()]) {
st.pop();
}
if (st.empty()) {
ans[i] = 0;
}
else {
ans[i] = st.top() - i;
}
st.push(i);
}
return ans;
题解思路
顺序单调栈
stack<int> st;
vector<int> ans(T.size(), 0);
for (int i = 0; i < T.size(); ++i) {
while (!st.empty() && T[i] > T[st.top()]) {
ans[st.top()] = i - st.top();
st.pop();
}
st.push(i);
}
return ans;