# **演算法作業 HW1** <font size=5>**1. 本週影片中提到的NP-complete問題有哪些?**</font> --- * Knapsack problem * Traveling salesperson problem * Partition problem * Art gallery problem <font size=5>**2. 請上網找一個老師沒說過的NP-complete問題,並舉個例子說明該問題的輸入與輸出。**</font> --- 圖著色問題(Graph Coloring Problem) * 定義:給定一個無向圖 **G = ( V , E )**,其中 **V** 為頂點集合,**E** 為邊集合,圖著色問題即為將 **V** 分為 **K** 個顏色組,每個組形成一個獨立集,即其中沒有相鄰的頂點。優化版本是希望獲得最小的 **K** 值。 * 舉例: 下圖是一個無向圖,用 **K** 個顏色將所有頂點上色,且相鄰點顏色不可相同,求最小值 **K** 。 ![](https://i.imgur.com/sCmyULD.png) 經過計算,可以得出下圖其中一種可能,最小值 **K** 為 3。 ![](https://i.imgur.com/NnAPFFO.png) <font size=5>**3. 二元搜尋應用:當數字可以重覆**</font> --- 數字可能重複,回傳找到最小index。 只要找到後不停止,繼續往左區間找就好了。 完全靠自己,花費時間:1分鐘。 ```c++ #include<iostream> #include<vector> #include<sstream> using namespace std; //數字重複,回傳找到最小index int binary_search(vector<int>nums,int target) { int l=0,r=nums.size()-1,mid,ans=-1; while(l<=r) { mid=(l+r)/2; if(nums[mid]==target)//找到跟target相同的數 { ans=mid; r=mid-1;//即使找到也繼續往左區間尋找 } else if(nums[mid]>target) { r=mid-1; } else { l=mid+1; } } return ans; } int main() { vector<int>nums; string s; int num,t; cout<<"輸入數列:"; getline(cin,s); stringstream s1; s1<<s; while(s1>>num) { nums.push_back(num); } cout<<"輸入要尋找的數:"; cin>>t; cout<<binary_search(nums,t)<<endl; return 0; } ``` 執行結果: ![](https://i.imgur.com/Y2JQNSg.png) ![](https://i.imgur.com/w50RZii.png) ![](https://i.imgur.com/dyfTlOV.png) <font size=5>**4. 二元搜尋應用:找數字該插入的位置**</font> --- [35. Search Insert Position - LeetCode](https://leetcode.com/problems/search-insert-position/) 若找不到數字則回傳應該插入的位置。 如果while迴圈跑到最後還是找不到,直接回傳左邊界的index即可。 完全靠自己,花費時間:一分鐘。 ```c++ class Solution { public: int searchInsert(vector<int>& nums, int target) { int l=0,r=nums.size()-1,mid; while(l<=r) { mid=(l+r)/2; if(nums[mid]==target) { return mid; } else if(nums[mid]>target) { r=mid-1; } else { l=mid+1; } } return l; } }; ``` ![](https://i.imgur.com/65PDEyQ.png) <font size=5>**5. 二元搜尋應用:找到最早出問題的版本**</font> --- [278. First Bad Version - LeetCode](https://leetcode.com/problems/first-bad-version/) 這題只是第三題的變體而已,同樣是找到後繼續往左區間找。 要注意的是用int會爆。 完全靠自己,花費時間:一分鐘。 ```c++ // The API isBadVersion is defined for you. // bool isBadVersion(int version); class Solution { public: int firstBadVersion(int n) { long l=1,mid,ans; while(l<=n) { mid=(l+n)/2; if(isBadVersion(mid)) { ans=mid; n=mid-1; } else { l=mid+1; } } return ans; } }; ``` ![](https://i.imgur.com/CzZeSZg.png) <font size=5>**6. 二元搜尋應用:開根號後的整數部分**</font> --- [69. Sqrt(x) - LeetCode](https://leetcode.com/problems/sqrtx/) 把x當右邊界r用二分搜下去找,找不到就回傳r。 一樣要注意用int會爆。 完全靠自己,完成時間:一分鐘。 ```c++ class Solution { public: int mySqrt(int x) { long l=1,r=x,mid; while(l<=r) { mid=(l+r)/2; if(mid*mid==x) { return mid; } else if(mid*mid>x) { r=mid-1; } else { l=mid+1; } } return r; } }; ``` ![](https://i.imgur.com/t8aM0x1.png) <font size=5>**7. 本週心得**</font> --- 有些題目因為做過了所以做蠻快的,還可以跟上,影片方面也沒什麼問題。 --- 若有錯誤歡迎指正