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;
	}
}

 

 

 

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