8.力扣2018年常見編程題總結(排序與檢索)

1.給定一組非負整數,重新排列它們的順序使之組成一個最大的整數。

輸入: [3,30,34,5,9] 輸出: 9534330

解:因爲結果可能爲很大,因此用string輸出,需要對兩兩字符進行拼接並返回最大的一個,因此可以採用字符串排序來實現

代碼:

#include<string>
#include <iostream>
#include<vector>
#include<algorithm>

using namespace std;
bool compare(string a, string b)
{
	return a + b > b + a;
}
class Solution {
public:
	string largestNumber(vector<int>& nums) {
		int length = nums.size();
		vector<string> tmp;
		for (int i = 0; i < length; i++)
			tmp.push_back(to_string(nums[i]));
		string s;
		sort(tmp.begin(), tmp.end(), compare);//對字符串數組拼接後進行排序
		for (int i = 0; i < length; i++)
		{
			s += tmp[i];//從大到小進行拼接
		}
		if (s[0]=='0')
		{
			return "0";
		}
		return s;
	}
};

int main()
{
	int numbers[5] = {4,2,1,3,5};
	vector<int> n = { 0,0 };
	Solution s1;
	cout<<s1.largestNumber(n);
}

2.給定一個無序的數組 nums,將它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]... 的順序。

示例 1:輸入: nums = [1, 5, 1, 1, 6, 4] 輸出: 一個可能的答案是 [1, 4, 1, 5, 1, 6]

解:對數組進行排序,然後將第n個元素與第n/2個元素分配給第一組,將第n-1個元素與第n/2-1個元素分配給第二組,將第n-2個元素與第n/2-2個元素分配給第三組

代碼:

using namespace std;

class Solution {
public:
	void wiggleSort(vector<int>& nums) {
		vector<int> tmp(nums);
		sort(tmp.begin(), tmp.end());
		int length = nums.size();
		int j = 1;
		for (int i = length-1; i > (length-1)/2; i--)
		{
			nums[j] = tmp[i];
			j += 2;
		}
		j = 0;
		for (int i = (length-1) / 2; i >=0; i--)
		{
			nums[j] = tmp[i];
			j += 2;
		}
	}
};

int main()
{
	vector<int> n = { 4,2,1,3,5 };
	Solution s1;
	s1.wiggleSort(n);
}

3.峯值元素是指其值大於左右相鄰值的元素。給定一個輸入數組 nums,其中 nums[i] ≠ nums[i+1],找到峯值元素並返回其索引。數組可能包含多個峯值,在這種情況下,返回任何一個峯值所在位置即可。

你可以假設 nums[-1] = nums[n] = -∞

輸入: nums = [1,2,3,1] 輸出: 2 解釋: 3 是峯值元素,你的函數應該返回其索引 2。

解:在一個while循環中通過比較左右數字大小移動兩邊的索引。當兩邊索引重合時即爲峯值處

代碼:

using namespace std;

class Solution {
public:
	int findPeakElement(vector<int>& nums) {
		int length = nums.size();
		if (length==0)
		{
			return 0;
		}
		int l = 0, r = length - 1;
		while (l<=r)
		{
			if (l == r) return l;
			int mid = (l + r) / 2;
			if (nums[mid] >= nums[mid + 1]) r = mid;
			else l = mid + 1;
		}
		return -1;
	}
};

int main()
{
	vector<int> n = { 1,2,3,1 };
	Solution s1;
	cout<<s1.findPeakElement(n);
}

4.給定一個包含 n + 1 個整數的數組 nums,其數字都在 1 到 之間(包括 1 和 n),可知至少存在一個重複的整數。假設只有一個重複的整數,找出這個重複的數。

輸入: [1,3,4,2,2] 輸出: 2

解:可以通過設置快慢指針進行搜索,快指針每次索引兩次,滿指針索引一次

代碼:

using namespace std;

class Solution {
public:
	int findDuplicate(vector<int>& nums)
	{
		int fast = 0, slow = 0;
		while (true) {
			fast = nums[nums[fast]];
			slow = nums[slow];
			if (slow == fast) {
				fast = 0;
				while (nums[slow] != nums[fast]) {
					fast = nums[fast];
					slow = nums[slow];
				}
				return nums[slow];
			}
		}
	}
};

int main()
{
	vector<int> n = { 1,2,3,1 };
	Solution s1;
	cout<<s1.findDuplicate(n);
}

5.給定一個整數數組 nums,按要求返回一個新數組 counts。數組 counts 有該性質: counts[i] 的值是  nums[i] 右側小於 nums[i] 的元素的數量。

輸入: [5,2,6,1]

輸出: [2,1,1,0]

解釋: 5 的右側有 2 個更小的元素 (2 和 1). 2 的右側僅有 1 個更小的元素 (1). 6 的右側有 1 個更小的元素 (1). 1 的右側有 0 個更小的元素.

解:利用二叉搜索樹完成,將數據插入的同時每個結點保存右邊比他小的結點的個數

代碼:

using namespace std;

class Solution {
public:

	class BSTNode
	{
	public:
		int val;
		int lesssize;
		BSTNode* left;
		BSTNode* right;
		BSTNode(int value) :val(value), lesssize(0), left(nullptr), right(nullptr) {
		}
	};

	class BST
	{
	public:
		BSTNode* root;
		BST() :root(nullptr) {}//構造函數
		int Insert(int i)
		{
			return Insert(i, root);
		}

		int Insert(int i, BSTNode* & cur)
		{
			if (cur == nullptr)
			{
				cur = new BSTNode(i);//當前結點爲根結點
			}
			else
			{
				if (cur->val == i)
				{
					return cur->lesssize + Insert(i, cur->right);
				}
				else if (cur->val < i)
				{
					return (1 + cur->lesssize + Insert(i, cur->right));
				}
				else if (cur->val > i)
				{
					cur->lesssize++;
					return Insert(i, cur->left);
				}
			}
			return 0;
		}
	};

	vector<int> countSmaller(vector<int>& nums) {
		BST bstTree;//將數據插入到二叉搜索樹中
		vector<int> res(nums.size(), 0);
		for (int i = nums.size() - 1; i >= 0; i--)
		{
			res[i] = bstTree.Insert(nums[i]);
		}
		return res;
	}
};

int main()
{
	vector<int> n = { 5,2,6,1 },s;
	Solution s1;
	s=s1.countSmaller(n);
	for (vector<int>::iterator i = s.begin(); i < s.end(); i++)
	{
		cout << *i << endl;
	}
}

 

 

 

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