TOP 96 - 100

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;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章