TOP 96 - 100

581. 最短无序连续子数组

我也是很疑惑为什么有那么多做法,自己一个也没想起来


题解思路1

使用sort,第一个和原数组不一样的元素的下标为左值,最后一个为右值。

vector 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 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 st;
vector 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 st;
vector 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;

你可能感兴趣的:(TOP 96 - 100)