1. 程式人生 > >無序陣列中找出和為N的兩個數 Two Sum

無序陣列中找出和為N的兩個數 Two Sum

如果是有序陣列,很簡單。兩頭指標往中間相遇即可。

因此對於無序陣列,排序即可。

唯一的麻煩題目要求的:要返回兩個數在排序之前原數組裡的序號。因此我需要在排序時也要保留原來的序列號。

這裡主要是以前不寫STL的程式。這裡用到vector。pair。sort。

vector常用到的vector.size()表示當前vector裡的資料個數。

初始化vector時用 vector<元素型別> v; 這樣就定義了一個空的vector。新增元素使用v.push_back()。訪問時可用v[i],但新增元素時不可以。

對vector排序可以使用stl自帶的方法:

sort(v.begin(), v.end(), myfun);
其中如果v的元素不是int這樣的簡單型別,需要自己寫一個myfun函式來告訴程式到底比較的是什麼。

pair是一個很好用的結構。

這裡我用pair把陣列的資料和編號繫結在了一起。

在最後我遇到了一個問題:

編譯出錯,搜到的解決訪問在這裡。

可能和類成員函式的函式原型有關。因為類的所有成員函式都有一個隱含的指標引數,即this。但是stl的所要求的sort自定義函式是不要this指標的。這就和sort需要的比較函式原型不一致了,所以就報錯了。所以設定成static函式,因為他天生不帶this指標。

class Solution {
public:
    static bool myfun(const pair<int, int> a, const pair<int, int> b)
    {
    	return a.first < b.first;
    }

    vector<int> twoSum(vector<int> &numbers, int target) {

		int i,j;
		vector< pair<int, int> > index;
		for(i=0;i<numbers.size();i++)
		{
			pair<int, int> tmp;
			tmp.first = numbers[i];
			tmp.second = i+1;
			index.push_back(tmp);
		}
		sort(index.begin(), index.end(), myfun);

        i = 0;
        j = index.size() - ;
        while(i<j)
        {
            if(index[i].first + index[j].first >target)
                j--;
            else if(index[i].first + index[j].first <target)
                i++;
            else
                break;
        }

		vector<int> result;
		int idx1,idx2;
		if(index[i].second < index[j].second)
		{
			idx1 = index[i].second;
			idx2 = index[j].second;
		}
		else
		{
			idx2 = index[i].second;
			idx1 = index[j].second;	
		}

        result.push_back(idx1);
        result.push_back(idx2);
        return result;
    }
};

Hash方法:可以考慮使用hash。將陣列的每個元素以元素值位key,下標為value存入hash表。然後第二次遍歷時,在hash中查詢target做減法後的差值,hash表中存在該差值就算找到了。注意一點:當陣列中存在重複元素時,注意hash表該如何查詢;兩個數不能為同一個數。

class Solution {
public:
    vector<int> twoSum(vector<int> &numbers, int target) {
        unordered_map<int, int> hashtable;
        vector<int> result;
        int n = numbers.size();
        for(int i=0;i<n;i++)
            hashtable[numbers[i]] = i+1;
            
        for(int i=0;i<n;i++)
        {
            int other = target - numbers[i];
            if(hashtable.find(other) != hashtable.end())
            {
                int j = hashtable[other];
                if(i+1 == j)
                    continue;
                result.push_back(i+1);
                result.push_back(j);
                break;
            }
        }
        return result;
    }
};

相關推薦

無序陣列N個數 Two Sum

如果是有序陣列,很簡單。兩頭指標往中間相遇即可。 因此對於無序陣列,排序即可。 唯一的麻煩題目要求的:要返回兩個數在排序之前原數組裡的序號。因此我需要在排序時也要保留原來的序列號。 這裡主要是以前不寫STL的程式。這裡用到vector。pair。sort。 vector常

(pyhon)給定一個整數陣列 nums 一個目標值 target,請你在該陣列目標值的那 個 整數,並返回他們的陣列下標。

方法一:使用最容易理解的遍歷陣列進行查詢 def solution(nums,target): #如果列表長度小於2,則直接結束 if len(nums) < 2: return #兩次迴圈列表,分別對列表中的所有可能的數字進行相加

陣列最大的個數

題目:從陣列區間A[lo, hi]中找出最大的兩個整數A[x1]和A[x2],要求元素比較的次數,要求儘可能的少 迭代版1: 如圖所示,當整個掃描一遍陣列A,找出最大的數x1後,再掃描一次陣

從給定陣列最大的個數——二分遞迴

分析1:對於給定陣列找出其中最大的兩個數,很容易想到的就是遍歷陣列。首先遍歷整個陣列,找出最大的一個元素並記錄下該位置;然後分別遍歷該位置之前的區間和該位置之後的區間,分別找出這兩個子區間的最大值,然

1.無序陣列個數使其等於給定值

碰到這種類似題目可以根據條件不同寫出不同時間複雜度的程式碼: 1.最暴力的遍歷,時間複雜度為O(n^2) 2.一般情況下先排序,再從兩邊向中間搜尋結果,時間複雜度為O(nlogn + n) int i = 0, j = numbers.size() - 1; while

程式設計師面試一百題-04-在二元樹某值的所有路徑

1-題目 : 輸入一個整數和一棵二元樹;從樹的根結點開始往下訪問一直到葉結點所經過的所有結點形成一條路徑;打印出和與輸入整數相等的所有路徑。 2-示例 : 輸入整數22和如下二元樹,則應答應出兩條路徑10-12和10-5-7。 3-思路 : 3.1-當訪問到某一結點時,把該結點

java 實現從無序陣列 第k大的數, 無序陣列充許有重複元素

要求找出第幾名的元素是什麼(找出B[i]的值)? 找出第k名的元素的值。          先從A中隨機一個下標index1, 然後進行一趟快速排序等到新陣列A1,排完了就知道index1對應的元素在A1中的新下標index2. 如果k等於index2,則A1[index2]就是要找的值。 如果 k小於in

二叉樹某一值的所有路徑

前段時間什麼也不懂,就跑到騰訊去面試,然後面試官出了這道題,當時已碰演算法就悶,現在給出這道題目的解 另外再次感謝July仁兄對於各種面試題的整理,讓我有這些經典的題來練習。 題目:輸入一個整數和一棵二元樹。 從樹的根結點開始往下訪問一直到葉結點所經過的所有結點形成一條路徑

每日一道演算法題4——在二元樹某一值的所有路徑

題目:輸入一個整數和一棵二元樹。從樹的根節點開始往下訪問一直到葉結點所經過的所有結點形成一條路徑。打印出和與輸入整數相等的所有路徑。 例如輸入整數22和如下二元樹 則打印出兩條路徑:10,12和10,5,7 參考程式碼: #include <i

演算法---從一個數組(或者集合)某個值的下標

public static int[] twoSum(int[] nums, int target) { //因為你要找到這兩個相加等於目標數,因此我認為你至少要遍歷一次 Map hashMap = new HashMap<>(); for

在二叉樹某一值的所有路徑-java實現

一個小演算法,分享一下思路: 描述: 寫一個程式建立一棵二叉樹,並按照一定規則,輸出二叉樹根節點到葉子節點的路徑。 規則如下: 1、從最頂端的根結點,到最下面的葉子節點,計算路徑通過的所有節點的和,如果與設定的某一值的相同,那麼輸出這條路徑上的所有節點。 2、從根節點遍歷

陣列單獨出現的2個數

一個整型數組裡除了兩個數字之外,其他的數字都出現了偶數次。請寫程式找出這兩個只出現一次的數字。 #include <iostream> using namespace std; void find_Two_Single_Num(int *arr, int &num1,

一個長度N陣列包含正數 負數 0,請實現一個函式0的最長子數列

<strong><span style="font-size:18px;">// #include<iostream> #include<vector>

長度n陣列重複的一個數字(數字範圍在0~n-1) 不採用hashmap

要求不採用hashmap public static void main(String[] args) { int[] nums = { 1, 2, 4, 3, 0 }; System.out.println(findDuplicate(nums)); Arrays.stream(num

在給定的陣列個元素給定值的所有元素對

Design an algorithm to find all pairs of integers within an array which sum to a specified value.  使用hash map: 1假設V為給定的值,A為給定的陣列。 2建立has

長度n的數組重復的一個數字(數字範圍在0~n-1) 不采用hashmap

static 一個 str for each light println 循環 pub 要求不采用hashmap public static void main(String[] args) { int[] nums = { 1, 2, 4, 3, 0 }; S

陣列一對元素,其是一個給定的目標數字。假設陣列只存在一個符合要求的數值對,返回這些數值的下標

【解題分析】對於陣列中某個下標i,如何判斷它是否屬於符合條件的兩個數字之一?最直觀的就是再次掃描數字,判斷target-array【i】是否存在於陣列中。這樣做時間複雜度O(n^2),效率不高,原因是沒有儲存之前的處理結果,每次都在做重複的工作。儘管效率不高,但

陣列個元素的等於指定數值,並輸出位置。

從陣列中找出和為指定值的第一對元素 1、這博文主要是實現了從陣列中找到兩個元素之和與指定值相等的元素,並輸出這兩個元素的陣列下標。 2、若有多對元素之和等於指定元素,那麼只需找到第一對並輸出結果即可。 程式思想及分析 1、通過快速排序對陣列進行排序,

陣列四個數字的等於指定數字(4Sum)

Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in

從倆個有序陣列第K小的數。要求時間複雜度O(logmin(m,n))

思路 該題目要求時間複雜度為O(log(min{m,n})) 所以不能直接遍歷任意一個數組這樣時間複雜度就不符合了。也不能對任意一陣列進行二分查詢,因為要求是倆個數組元素合併後的第K小的數,所以直接遍歷用二分遍歷任意一個數組也是行不通的。 故我們可以以