6.力扣2018年常見編程題總結(哈希與映射)

1.給定一個Excel表格中的列名稱,返回其相應的列序號。

例如, A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -> 27 AB -> 28

解:字符串只有一個的情況下爲s[i]-'A'+1,兩個字符串的情況下需要進行拆分,(s[0]-'A'+1)*26+(s[1]-'A'+1)

代碼:

#include<string>
#include <iostream>
using namespace std;

class Solution {
public:
	int titleToNumber(string s) {
			int res = 0, temp = 0;
			for (int i = 0; i < s.size(); i++)
			{
				temp = (int)(s[i] - 'A' + 1);
				res = res * 26 + temp;
			}
			return res;
		}
};

int main()
{
	Solution s1;
	string s = "zyy";
	cout << s1.titleToNumber(s) << endl;
}

2.給定四個包含整數的數組列表 A , B , C , D ,計算有多少個元組 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0

例如:

輸入: A = [ 1, 2] B = [-2,-1] C = [-1, 2] D = [ 0, 2]

輸出: 2

解釋: 兩個元組如下:

1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0

2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0

解:利用map映射來實現,將四個數組分爲2份,先將CD數組的值進行求和統計將結果放在map中,再用0-AB數組中的內容看能否在map中找到對應的值,若找到則代表它們四個加起來爲0

代碼:

#include <iostream>
#include<stack>
#include<vector>
#include<unordered_map>
using namespace std;

class Solution {
public:
	int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
		unordered_map<int, int> record;
		for (int i = 0; i < C.size(); i++)
		{
			for (int j = 0; j < D.size(); j++)
			{
				record[C[i] + D[j]]++;
			}
		}
		int res = 0;
		for (int i = 0; i < A.size(); i++)
		{
			for (int j = 0; j < B.size();j++)
			{
				if (record.find(0-A[i]-B[j])!=record.end())
				{
					res += record[0 - A[i] - B[j]];
				}
			}
		}
		return res;
	}
};

int main()
{
	Solution s1;
	vector<int> A = { 1, 2 };
	vector<int> B = { -2,-1 };
	vector<int> C = { -1, 2 };
	vector<int> D = { 0, 2 };
	cout << s1.fourSumCount(A,B,C,D) << endl;
}

3.設計一個支持在平均 時間複雜度 O(1) 下,執行以下操作的數據結構。

insert(val):當元素 val 不存在時,向集合中插入該項。

remove(val):元素 val 存在時,從集合中移除該項。

getRandom:隨機返回現有集合中的一項。每個元素應該有相同的概率被返回。

// 初始化一個空的集合。

RandomizedSet randomSet = new RandomizedSet();

// 向集合中插入 1 。返回 true 表示 1 被成功地插入。

randomSet.insert(1);

// 返回 false ,表示集合中不存在 2 。

randomSet.remove(2);

// 向集合中插入 2 。返回 true 。集合現在包含 [1,2] 。

randomSet.insert(2);

// getRandom 應隨機返回 1 或 2 。

randomSet.getRandom();

// 從集合中移除 1 ,返回 true 。集合現在包含 [2] 。

randomSet.remove(1);

// 2 已在集合中,所以返回 false 。

randomSet.insert(2);

// 由於 2 是集合中唯一的數字,getRandom 總是返回 2 。

randomSet.getRandom();

解:由於要求的操作時間複雜度在O(1)下,因此需要考慮用映射來實現,對於插入元素,首先需要檢查是否在之前的數組中已經存在,若存在則直接返回false。若不存在則將插入的元素與當前數組的大小放置在map中,當前數組的大小對應於數組中的索引值,之後將元素插入大數組中。

對於刪除元素,首先需要檢查元素是否在map中,若不存在則直接返回false,若存在則需要知道map中該值對應的索引,交換數組中當前值與最後一個值,數組大小resize爲原來的-1,修改map,將當前值的value改爲index。刪除該值。

代碼:

#include<vector>
#include<set>
#include<unordered_map>
using namespace std;

class RandomizedSet {
public:
	/** Initialize your data structure here. */
	RandomizedSet() {}

	/** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
	bool insert(int val) {
		if (hashMap.find(val) != hashMap.end(0)) return 0;//插入了一個重複的元素
		hashMap.insert(make_pair(val,nums.size()));//插入元素以及當前數組中的個數
		nums.push_back(val);
		return 1;
	}

	/** Removes a value from the set. Returns true if the set contained the specified element. */
	bool remove(int val) {
		if (hashMap.find(val) == hashMap.end()) return 0;//沒有找到要刪除的元素
		int index = hashMap.find(val)->second;
		if (index == nums.size() - 1)
			nums.resize(nums.size() - 1);
		else
		{
			swap(nums[index], nums[nums.size() - 1]);
			nums.resize(nums.size() - 1);
			hashMap[nums[index]] = index;
		}
		hashMap.erase(val);
		return true;
	}

	/** Get a random element from the set. */
	int getRandom() {
		return nums[rand() % nums.size()];
	}
private:
	vector<int> nums;
	unordered_map<int, int> hashMap;
};


int main()
{
	RandomizedSet* obj = new RandomizedSet();
	cout<<obj->insert(2)<<endl;
	cout<<obj->insert(1)<<endl;
	cout<<obj->insert(3)<<endl;
	cout <<obj->remove(2) << endl;
	cout << obj->getRandom() << endl;
}

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章