1. 程式人生 > >算法題解題思路及代碼(不定時更新)

算法題解題思路及代碼(不定時更新)

希望 target 解答 時間 -s 一次 return 時間復雜度 2.3

畢業半年, 平時工作總是關註業務、架構,而卻越來越少關註性能, 也再也沒有做過任何涉及算法的工作了

希望有時間把這些拉下的東西拾起來,畢竟不論是使用什麽語言,從事什麽行業,只要是程序員,算法才是真正的基礎。

題目來自leetcode,代碼語言通常為C/C++,後期可能個別題目會用Golang


萬事開頭難,但堅持下去其實更難。

(2018.2.3)



題目1:給定和,獲取加數

描述: 給定一個整數數組,以及一個整數,已知這個整數是數組內某兩個元素的和,現在需要找到,並返回這兩個元素的索引,例如:

整數數組:{11, 7, 12, 2}

整數 :9

返回結果:{1, 3}

(假定結果一定存在於給定數組,並且不需要考慮存在多組結果)

題目鏈接:https://leetcode.com/problems/two-sum/description/


解答:

1、最傳統的方法就是挨個查找,判斷結果,具體步驟是:

每一趟都從下圖第一個元素(11)開始, 固定住第一個元素不變,計算當前元素與其後每個元素的值之和,判斷是否等於目標整數

這種方法,最壞的情況下,數組內每一對元素都會被計算一次,因此時間復雜度為O(N * N)

技術分享圖片

代碼:

vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> ret;
        int sz = nums.size();
        for(size_t i = 0; i < sz - 1; ++i) {
            for(size_t j = i + 1; j < sz; ++j) {
                if(nums[i] + nums[j] == target) {
                    ret.push_back(i);
                    ret.push_back(j);
                    return ret;
                }
            }
        }
        return ret;
    }

2、上面的貪婪法可以將步驟分解為兩部分,外層循環和內層循環,每當外層循環執行一步,內層循環都需要逐個遍歷剩下的元素,執行一趟時間復雜度為O(N)的過程,在整個過程中,外層循環是無法優化的,而內層的循環作為優化,可以考慮用空間換取時間的思路:即事先對整個數組建立索引,使得每一趟的內層循環不再是遍歷,而是精確查找,使得算法的時間復雜度由O(N*N)變為O(N*1)

具體步驟是:

技術分享圖片


3、建立索引的過程可以分解到外層循環的每一步當中:

一開始無索引,每一步都在索引中查找目標元素,如果沒有,則將當前元素存入索引,並叠代至下一步


比較1、2、3方法,

1方法時間復雜度為O(N*N),最低效,

2、3方法整體時間復雜度都是O(N),區別在於 2方法是在一開始就建立了完整的索引,而3方法則是在叠代的過程中逐步建立索引

在悲觀的情況下,2、3方法效率是相同的

在樂觀的情況下,3方法只需要向索引中存放一個元素,因此相對來說更高效

算法題解題思路及代碼(不定時更新)