演算法設計與分析(七) Graph And Tree

2021-08-30 06:49:43 字數 2498 閱讀 4249

example 1:

input: [ [1,2], [2,3], [3,4], [1,3] ]

output: 1

example 2:

input: [ [1,2], [1,2], [1,2] ]

output: 2

example 3:

input: [ [1,2], [2,3] ]

output: 0

本題要將一堆區間中的某些區間去掉,使得剩下的區間中沒有重疊的部分。而且要求找到最優的篩選法,使得需要刪除的次數最少。

如何使得刪除的次數最少呢?我們可以稍稍「貪婪」一點地想。如果每次我們都將與剩下區間中重疊的區間數最多的那個區間去掉,是不是就是我們這次刪選的最優選擇呢?

很難從數學上證明這種思路是否正確,不過直觀上覺得這是最好的刪選方式。既然有了這種想法,試試就知道是否正確。

聯想資料結構中的鄰接矩陣,我們可以將有重疊的區間視為「相鄰」的,以此可以構造出乙個區間們的「鄰接矩陣」,0代表兩個區間不相鄰,1代表相鄰:

int len = intervals.size();

if(len == 0) return 0;

將每個區間的相鄰區間數儲存起來:

//vectornums(len,0);
顯然,當nums中仍有元素大於0時,說明區間中仍有重疊。

如何判斷兩個區間是否有重疊呢?情況比較多。這時我們可以反過來思考:如何判斷兩個區間沒有重疊呢?這就簡單了。只要某個區間的大端小於另乙個區間的小端。不符合這種的就是有重疊的:

for(int i = 0;i < len;i ++) }}

nums[i] = count;

}

現在開始迴圈驗證:找到nums中最大的元素,如果該元素不為0,將該元素對應的區間刪除,nums置零,並且搜尋鄰接矩陣中該區間的那一行,將其中值為1的對應區間的nums值減一,因為他的乙個響鈴區間被刪掉了。

重複該操作,直到nums中沒有大於0的元素為止:

int max = -1;

while(true)

}if(max == 0) break;

for(int i = 0;i < len;i ++)

}ans ++;

}

做完之後驗證,發現結果是不對的。問題在那裡呢?

我們沒有考慮一種特殊的情況:佇列中的相同區間(例如【1,2】、【1,2】)。我們將這種區間簡單地視為普通的重疊區間而已。這種思考有問題。顯然,這種相同區間是一定要刪除的,而且應該盡早刪除,因為其他區間只要與這種區間相鄰,就會增加一大堆的相鄰數。這是一種刪除優先順序比相鄰數更高的區間,所以我們要提前考慮,刪除它們:

for(int i = 0;i < len;i ++) 

}ans ++;

break;

}}}

這種方式的時間複雜度和空間複雜度都很高,其時間複雜度需要刪除的區間數和相同區間數影響,而且**複雜冗長。

我在討論中找到了一種更好的方法。

直接將區間陣列按照區間起點從小到大排序,從第乙個區間開始遍歷,如果前乙個區間的結尾大於下乙個區間的開始,說明兩個區間中有乙個區間要刪除;刪除哪乙個呢?刪除結尾較大的那個,這樣剩下的那個區間與其他區間重疊的機會更小。

如何驗證這種方式是最優的呢?其實不好驗證,這是一種經驗性的總結。如果有讀者,想要證明的可以自己嘗試挑戰一下。

附上兩種方式的完整**;

/**

* definition for an interval.

* struct interval

* interval(int s, int e) : start(s), end(e) {}

* };

*/class solution }}

//nums[i] = count;

}for(int i = 0;i < len;i ++)

}ans ++;

break;}}

}int max = -1;

while(true)

}if(max == 0) break;

for(int i = 0;i < len;i ++)

}ans ++;

}return ans;

}};

class solution ;

sort(intervals.begin(), intervals.end(), comp);

int res = 0, pre = 0;

for (int i = 1; i < intervals.size(); i++)

else pre = i;

}return res;

}};

演算法設計與分析 第七周 IPO

4 與改進 第二版4.3第三版 4.4bug版 5源 學習了貪心演算法,隨機選擇了一道題目。貪心演算法的本質即是 每一步都選擇當前最好的點,不一定能夠得到全域性最優解,但一定要得到區域性最優解。結合這道題來考慮,按照貪心演算法的思路,在當前步,我算要考慮的就是我手中所能投資的專案中獲利最大的。有了思...

演算法設計與分析

輸入輸出 確定性有窮性 np類問題是非確定性計算模型下的易驗證問題類。所有可以在多項式時間內求解的判定問題構成p類問題 1 二分搜尋技術 二分搜尋演算法的基本思路是對給定已排好序的n個元素a 0 n 1 在這n個元素中找出乙個特定元素x。運用分治的思想,將n個元素以n 2為中心對半分。if x a ...

演算法分析與設計

分析,此題可以用動態規劃來做。子問題為 max i max i 1 0 max i 1 nums i nums i max i 表示以nums i 結尾的子串的最大和,最後返回最大的那個即為所求,複雜度為o n class solution return max 另一種實現方法,更加簡潔,即從前往後...