1 兩數之和

雖然只是一道很簡單的題,但是也給我很多思考。

剛看到這道題的時候沒有仔細思考,直接寫了個排序和二分查找,想著對每個數字查找另一個數字會不會出現,復雜度是O(nlogn+nlogn)O(nlogn+nlogn)O(nlogn+nlogn),主要訓練了一下自己手寫快速排序和二分查找。

class Solution {void swap(vector<int>& a,vector<int>& b,int i,int j){int t=a[i]; a[i]=a[j]; a[j]=t;t=b[i]; b[i]=b[j]; b[j]=t;}void getPovit(vector<int>& a, vector<int>& b,int l,int r){//三者取中得到樞紐int mid = (l+r) >> 1;if(a[l] < a[mid]) swap(a, b, l, mid);if(a[r-1] < a[mid]) swap(a, b, r-1, mid);if(a[l] > a[r-1]) swap(a, b, l, r-1);}void quickSort(vector<int>& a,vector<int>& b, int l,int r){if(r-l < 2) return;int mid = (l+r) >> 1;getPovit(a, b, l, r);int povit = a[l];int i=l-1; int j=r;while(i<j){do ++i; while(a[i] < povit);do --j; while(a[j] > povit);if(i < j) swap(a, b, i, j);}quickSort(a, b, l, j+1);quickSort(a, b, j+1, r);}int bSearch(vector<int>& a, int l,int r,int x,int now){if(r<=l) return -1;int mid = (l+r) >> 1;if( a[mid] == x && mid != now) return mid;if(a[mid] < x) return bSearch(a, mid+1, r, x, now);else return bSearch(a, l, mid, x, now);}
public:vector<int> twoSum(vector<int>& nums, int target) {vector<int> b;int n = nums.size();for(int i=0; i<n; ++i){b.push_back(i);}quickSort(nums, b, 0, n);// sort(nums.begin(), nums.end());vector<int> ret;for(int i=0; i<n; ++i){int tmp = target - nums[i];int j = bSearch(nums, 0, n, tmp, i);if(-1 != j){ret.push_back(b[i]); ret.push_back(b[j]);break;}}return ret;}
};

上面的做法很傻,稍微聰明一點的做法是排序以后從兩邊開始查找。這樣的復雜度是O(nlogn+n)O(nlogn+n)O(nlogn+n)的。因為我們求的是兩個數字的和,所以對于一個排好序的數組來講,如果一個數字增大,另一個數字一定減小。因此我們用兩個指針,一個指向數組的頭部,一個指向數組的尾部,如果出現所求的和就直接返回答案,如果兩個指針和比目標小就將前一個指針后移,如果比目標大就把后一個指針前移。這種直覺很容易證明是正確的。

class Solution {void swap(vector<int>& a,vector<int>& b,int i,int j){int t=a[i]; a[i]=a[j]; a[j]=t;t=b[i]; b[i]=b[j]; b[j]=t;}void getPovit(vector<int>& a, vector<int>& b,int l,int r){//三者取中得到樞紐int mid = (l+r) >> 1;if(a[l] < a[mid]) swap(a, b, l, mid);if(a[r-1] < a[mid]) swap(a, b, r-1, mid);if(a[l] > a[r-1]) swap(a, b, l, r-1);}void quickSort(vector<int>& a,vector<int>& b, int l,int r){if(r-l < 2) return;int mid = (l+r) >> 1;getPovit(a, b, l, r);int povit = a[l];int i=l-1; int j=r;while(i<j){do ++i; while(a[i] < povit);do --j; while(a[j] > povit);if(i < j) swap(a, b, i, j);}quickSort(a, b, l, j+1);quickSort(a, b, j+1, r);}int bSearch(vector<int>& a, int l,int r,int x,int now){if(r<=l) return -1;int mid = (l+r) >> 1;if( a[mid] == x && mid != now) return mid;if(a[mid] < x) return bSearch(a, mid+1, r, x, now);else return bSearch(a, l, mid, x, now);}
public:vector<int> twoSum(vector<int>& nums, int target) {vector<int> b;int n = nums.size();for(int i=0; i<n; ++i){b.push_back(i);}quickSort(nums, b, 0, n);// sort(nums.begin(), nums.end());int i = 0, j = n-1;while(i < j){if(nums[i] + nums[j] == target)return vector<int>{b[i], b[j]};if(nums[i] + nums[j] < target)++i;else --j; }return vector<int>();}
};

官方給出的題解是通過使用HashMap解決的,發現這樣的效率很好,然而我之前沒有接觸過HashMap,通過一番學習,用HashMap解決了一下。

class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int, int> hashMap;unordered_map<int, int>::const_iterator it;int n = nums.size();hashMap[nums[0]] = 0;for(int i=1; i<n; ++i){it = hashMap.find(target - nums[i]);if(it != hashMap.end()){return vector<int>{it->second, i};}hashMap[nums[i]] = i;}return vector<int>();}
};

但是也沒有覺得快多少,可能是因為數據比較水看不出來差距吧。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/383594.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/383594.shtml
英文地址,請注明出處:http://en.pswp.cn/news/383594.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

834 樹中距離之和

這道題我自己的想法只有對每個點都用一遍Dijkstra然后再求和&#xff0c;顯然會超時&#xff0c;所以我都沒有嘗試。 研究了一下題解&#xff0c;發現題解很巧妙&#xff0c;自己對樹的處理還是太稚嫩&#xff0c;之前樹鏈剖分學的都忘光了。 對于固定根節點的&#xff0c;我…

75 顏色分類

題目已經提示可以一遍掃描了但是我還是沒有想到&#xff0c;其實雙指針的想法我已經有了&#xff0c;但是一想到有問題就覺得無法實現。這也揭示了我思維上的問題&#xff1a;用一種方法解決問題遇到困難第一件事情不是想著如何攻克而是想著換一種方法。對自己的思維也不自信。…

141 環形鏈表

要求使用空間復雜度為O(1)的方法&#xff0c;可是我并沒有想到。我想到的只有用一個哈希表記錄一下所有訪問過的節點。 題解給出的空間復雜度為O(1)的方法是使用兩個指針&#xff0c;然后讓一個一次跑一步&#xff0c;一個一次跑兩步&#xff0c;如果跑的快的能追上跑的慢的就…

數據可視化【十五】

經驗法則&#xff1a;在顏色不相鄰的時候加上背景顏色顏色的個數為6~12比較好。 顏色其實很大程度上由背景決定而不是他本身決定。 D3 Scale-Chromatic 有許多顏色刻度&#xff0c;可以根據自己的需要進行選擇。 參考論文&#xff1a;Practical Rules for Using Color in Cha…

Ubuntu修改/刪除主目錄下的中文文件夾

在Ubuntu的主目錄下一般是有一些中文的目錄&#xff0c;例如桌面&#xff0c;視頻等等&#xff0c;還無法修改名稱&#xff0c;在一群英文文件夾里面顯得有些突兀&#xff08;Ubuntu終端下的中文一點也不好看&#xff09;&#xff0c;就想把這些文件夾修改一下&#xff0c;結果…

19 刪除鏈表的倒數第N個

題目的意思很簡單&#xff0c;就是刪除一個鏈表倒數第N個節點。 需要用到鏈表的標準操作&#xff1a;快慢指針。 我們讓一個快指針先指向第N個元素&#xff0c;這個時候快指針總比慢指針領先N個元素&#xff0c;等到快指針指向鏈表尾部的時候慢指針就指向需要刪除的元素。 之前…

844. Backspace String Compare

題目的意思大概是有兩個字符串&#xff0c;其中的#表示退格鍵&#xff0c;讓比較最后兩個字符串是否相當。 很容易想到的思路就是用一個棧進行模擬這個過程&#xff0c;特別需要注意如果一個串是空串也是可以退格的。 但是很容易想到的另一個特性就是&#xff0c;前面的字符有…

鏈表三連擊

876&#xff1a;鏈表的中間節點 206&#xff1a;反轉鏈表 143&#xff1a;重排練表 鏈表的中間節點 這個題一看就是最簡單的快慢指針&#xff0c;但是在具體實現的時候我還是猶豫思考了一下&#xff1a;要不要在鏈表前面放置啞節點&#xff0c;快指針應該什么時候判斷已經到達…

D3力導引圖

學習力導引圖的時候在網上沒有找到什么好的教程&#xff0c;支離破碎地進行了一段時間的學習&#xff0c;還閱讀了d3的關于d3的官方文檔&#xff0c;但是始終覺得不的要領。這里記錄一下我學習力導引圖的一些心得以及推薦一下學習資源。 學習資源 官方文檔&#xff1a;https:…

Ubuntu Pycharm啟動后卡住無法操作

昨天還好好的&#xff0c;今天打開Pycham突然卡住了&#xff0c;卡在了那個preparing workspace的地方&#xff0c;然后在網上搜索了很多方法都沒用。直到在網上看到有個大佬說是因為搜狗輸入法的問題&#xff0c;我才突然記起來昨天安裝了搜狗輸入法。。。 kill掉卡住的Pycha…

327 區間和的個數

題目描述 Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive. Range sum S(i, j) is defined as the sum of the elements in nums between indices i and j (i ≤ j), inclusive. Note: A naive algorithm of O(n2) is t…

瀏覽器訪問本地文件

之前一直苦惱無法在瀏覽器訪問本地文件&#xff0c;尤其是寫的網頁需要調用外部數據的時候&#xff0c;今天學習到可以用python很方便的解決問題 如果有python3環境&#xff0c;直接在對應的文件夾下運行&#xff08;這里是Ubuntu環境&#xff0c;如果是Windows應該在命令行也…

Ubuntu使用jupyter notebook +導出PDF

因為最近需要做數據分析的工作&#xff0c;所以復習了一下numpy和pandas&#xff0c;并安裝了jupyter notebook進行數據分析&#xff0c;這里記錄一下環境的設置。 ps:jupyter notebook真香 安裝 python3 -m pip install --upgrade pip //升級pip pip3 install jupyter使用 …

SSH:WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

給服務器重裝了一下系統&#xff0c;結果報了上述錯誤&#xff1a; WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! ...在網上找…

Ubuntu20.04 更新后黑屏無法加載驅動

本來我的電腦好好的&#xff0c;突然提示說有可應用的更新&#xff0c;我想都沒想就直接更新了&#xff0c;可是沒想到更新以后經過grub以后就會黑屏&#xff0c;一動不動&#xff0c;在網上搜索了許多&#xff0c;提到的說法是在grub界面對第一個Ubuntu的啟動按e進行編輯 在倒…

每日一題:leetcode1489. 找到最小生成樹里的關鍵邊和偽關鍵邊

時隔多年我終于又開始寫博客了&#xff0c;主要是已經放假了&#xff0c;之前一直忙于考試和課設沒有時間寫博客&#xff0c;學習筆記也因為買了iPad的緣故大部分都是手寫的了。 假期想要把以前做過的項目都整理一下放在github和CSDN上。 也已經很久沒有寫算法題了&#xff0…

每日一題:leetcode989.數組形式的整數加法

題目描述 題目分析 題目非常簡單&#xff0c;但是我還是wa了幾發&#xff0c;對不起&#xff0c;我太菜了。我的想法是把K轉換為數組然后用大整數加法處理。但是因為太久沒有寫了導致寫了好久。 class Solution { public:void add(vector<int> &A, vector<int&g…

每日一題:leetcode674.最長連續遞增序列

題目描述 題目分析 一遍遍歷&#xff0c;如果硬要說用了什么算法的話覺得應該算是一個簡單的滑動窗口吧 AC代碼 class Solution { public:int findLengthOfLCIS(vector<int>& nums) {if (nums.size() 0) {return 0;}int ret 1;int cnt 1;for (int i 1; i <…

每日一題:leetcode959.由斜杠劃分區域

題目描述 題目分析 仔細分析這道題以后雖然覺得可能要轉化為圖之類的&#xff0c;但是完全沒有具體的想法&#xff0c;因為每個格子都有三種情況&#xff0c;這三種情況的不同的組合又會產生不同的結果。 發現找不到編碼轉化為圖以后&#xff0c;我分析了一下不同數量方塊之間…

每日一題:leetcode1319.聯通網絡的操作次數

題目描述 題目分析 ps&#xff1a;這篇博客是補前天的&#xff0c;前天在老家不方便寫博客 題目挺簡單的&#xff0c;但是通過題目對圖的連通性有了一個更深刻的認識&#xff1a;如果有超過&#xff08;或等于&#xff09;n-1條邊&#xff0c;則一定是可以讓整個圖聯通的。 如…