算法刷题训练营(三)

算法刷题训练营(三)

题目一:

在这里插入图片描述

上面这种利用lambad表达式进行sort自定义的方法要掌握,面试的时候可没有时间让你自己试。。。。。
如果想从小到大排,就顺序<,从大到小排就顺序>。可以把两个参数的位置看成定死的。

sort(job.begin(), job.end(), [](const Job& job1,const Job& job2)
	{
		return job1.hard != job2.hard ? job1.hard < job2.hard : job1.money>job2.money;
	});
	return job;
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
#include<numeric>
using namespace std;

class Job
{
public:
	int hard;
	int money;
	Job(int h,int m):hard(h),money(m){}
	friend ostream& operator<<(ostream& os, const Job& job1)
	{
		os << "(" << job1.hard << "," << job1.money << ")" << endl;
		return os;
	}
};

vector<int> getMoney(vector<Job>& job, vector<int>& ability)
{
	//难度是从小到达,同级别内报酬是从大到小的。
	sort(job.begin(), job.end(), [](const Job& job1,const Job& job2)
	{
		return job1.hard != job2.hard ? job1.hard < job2.hard : job1.money>job2.money;
	});
	for (auto o : job)
	{
		cout << o << endl;
	}
	//难度为key的工作,最优钱数是多少,有序表。
	map<int, int> a;
	//a.insert(pair<int,int>(job[0].hard, job[0].money));
	a[job[0].hard] = job[0].money;
	
	Job pre = job[0];
	int n = job.size();
	for (int i = 1; i < n; i++)
	{
		if (job[i].hard != pre.hard && job[i].money > pre.money)
		{
			pre = job[i];
			a.insert(pair<int,int>(pre.hard, pre.money));
		}
	}

	vector<int> ans;

	for (uint32_t i = 0; i < ability.size(); i++)
	{
		/*
		if (a.count(ability[i]) > 0)
		{
			ans[i] = a[ability[i]];
		}
		else
		{
			ans[i] = 0;
		}
		*/
		int maxa = 0;
		for (auto it = a.begin(); it != a.end(); it++)
		{
			if (ability[i] >= (*it).first)
			{
				maxa = max(maxa, (*it).second);
			}
		}
		ans.push_back(maxa);
	}
	return ans;
}
int main()
{
	vector<Job> job = { Job(1,2),Job(1,1),Job(2,6),Job(1,5),Job(3,2),Job(4,8),Job(3,7),Job(4,6) };
	vector<int> ability = {0,1,2,3,4,5,6,7};
	
	vector<int> aa = getMoney(job, ability);
	for (auto a : aa)
	{
		cout <<a<< endl;
	}
	system("pause");
	return 0;
}
题目二

在这里插入图片描述

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


// 从左往右的经典模型
// 还剩的容量是rest,arr[index...]自由选择,
// 返回选择方案
// index : 0~N
// rest : 0~w
int process(vector<int>& arr, int index, int rest)
{
	if (rest < 0)
	{
		//没有容量了
		//-1 无方案的意思
		return -1;
	}
	//rest>=0;
	if (index == arr.size())
	{
		//无零食可选
		return 1;
	}
	// rest >=0
	// 有零食index
	// index号零食,要 or 不要
	// index, rest
	// (index+1, rest)
	// (index+1, rest-arr[i])
	int next1 = process(arr, index + 1, rest);//不选择当前位置;
	int next2 = process(arr, index + 1, rest - arr[index]);//要
	return next1 + (next2 == -1 ? 0 : next2);
}
int way(vector<int>& arr, int w)
{
	process(arr, 0, w);
}

int way1(vector<int>& arr, int w)
{
	int n = arr.size();

	vector<vector<int>> dp(n + 1, vector<int>(w + 1));
	for (int j = 0; j <= w; j++)
	{
		dp[n][j] = 1;
	}
	for (int i = n - 1; i >= 0; i--)
	{
		for (int j = 0; j <= w; j++) 
		{
			dp[i][j] = dp[i + 1][j] + ((j - arr[i] >= 0) ? dp[i + 1][j - arr[i]] : 0);
		}
	}
	return dp[0][w];
}
int ways3(vector<int>& arr, int w) 
{
	int n = arr.size();
	vector<vector<int>> dp(n, vector<int>(w + 1));
	for (int i = 0; i < n; i++) 
	{
		dp[i][0] = 1;
	}
	if (arr[0] <= w) 
	{
		dp[0][arr[0]] = 1;
	}
	for (int i = 1; i < n; i++) 
	{
		for (int j = 1; j <= w; j++) 
		{
			dp[i][j] = dp[i - 1][j] + ((j - arr[i]) >= 0 ? dp[i - 1][j - arr[i]] : 0);
		}
	}
	int ans = 0;
	for (int j = 0; j <= w; j++) 
	{
		ans += dp[n - 1][j];
	}
	return ans;
}
题目三

在这里插入图片描述

#include<iostream>
#include<vector>

using namespace std;

int minPathSum(vector<vector<int>>& matrix)
{
	int m = matrix.size();
	int n = matrix[0].size();

	if (m == 0 || n == 0)return 0;
	vector<vector<int>> dp(m, vector<int>(n));
	dp[0][0] = matrix[0][0];

	for (int i = 1; i < m; i++)
	{
		dp[i][0] = dp[i - 1][0] + matrix[i][0];
	}
	for (int j = 1; j < n; j++)
	{
		dp[0][j] = dp[0][j - 1] + matrix[0][j];
	}
	for (int i = 1; i < m; i++)
	{
		for (int j = 1; j < n; j++)
		{
			dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + matrix[i][j];
		}
	}
	return dp[m - 1][n - 1];
}
int minPathSum2(vector<vector<int>>& matrix)
{
	int m = matrix.size();
	int n = matrix[0].size();

	int more = max(m, n);
	int less = min(m, n);

	bool rowmore = more == m;
	vector<int> arr(less);
	arr[0] = matrix[0][0];

	for (int i = 1; i < less; i++) {
		arr[i] = arr[i - 1] + (rowmore ? matrix[0][i] : matrix[i][0]);
	}
	for (int i = 1; i < more; i++) {
		arr[0] = arr[0] + (rowmore ? matrix[i][0] : matrix[0][i]);
		for (int j = 1; j < less; j++) {
			arr[j] = min(arr[j - 1], arr[j])
				+ (rowmore ? matrix[i][j] : matrix[j][i]);
		}
	}
	return arr[less - 1];
}
题目四

在这里插入图片描述

#include<iostream>
#include<vector>

using namespace std;

// str1[0....i1] 与 str2[0......i2]的最长公共子序列长度是多少?
int process(string str1, int i1, string str2, int i2)
{
	if (i1 == 0 && i2 == 0)
	{
		return str1[i1] == str2[i2] ? 1 : 0;
	}
	//i1和i2不同时为0
	if (i1 == 0)
	{
		return ((str1[i1] == str2[i2]) || process(str1, i1, str2, i2 - 1) == 1) ? 1 : 0;
	}
	if (i2 == 0)
	{
		return ((str1[i1] == str2[i2]) || process(str1, i1 - 1, str2, i2) == 1) ? 1 : 0;
	}
	//i1和i2都不是0;
	//最长公共子序列结尾好,不是以str1[i1]与str2[i2]结尾的。
	int p1 = process(str1, i1 - 1, str2, i2 - 1);
	int p2 = process(str1, i1, str2, i2 - 1);
	int p3 = process(str1, i1 - 1, str2, i2);
	int p4 = 0;
	if (str1[i1] == str2[i2])
	{
		p4 = p1 + 1;
	}
	return max(max(p1, p2), max(p3, p4));
}

int lcs(string s1, string s2)
{
	int m = s1.size();
	int n = s2.size();

	return process(s1, m - 1, s2, n - 1);
}

上面的递归改动态规划

//上面的递归改动态规划
int dp(string s1, string s2)
{
	int m = s1.size();
	int n = s2.size();
	vector<vector<int>> dp(m, vector<int>(n));

	dp[0][0] = s1[0] == s2[0] ? 1 : 0;

	for (int i = 1; i < m; i++)
	{
		dp[i][0] = s1[i] == s2[0] ? 1 : dp[i - 1][0];//dp表第一列的元素
	}
	for (int j = 1; j < n; j++)
	{
		dp[0][j] = s1[0] == s2[j] ? 1 : dp[0][j - 1];//dp表第一行的元素
	}
	for (int i = 1; i < m; i++)
	{
		for (int j = 1; j < n; j++)
		{
			dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
			if (s1[i] == s2[j])
			{
				dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1);
			}
		}
	}
	return dp[m - 1][n - 1];
}

题目五

在这里插入图片描述

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

//dp表的含义是s1以i位置结尾,s2以j位置结尾,最长公共子串的长度。
vector<vector<int>> getdp(string s1, string s2)
{
	int m = s1.size();
	int n = s2.size();
	vector<vector<int>> dp(m, vector<int>(n));
	for (int i = 0; i < m; i++)
	{
		if (s1[i] == s2[0])
		{
			dp[i][0] = 1;
		}
	}
	for (int j = 1; j < n; j++)
	{
		if (s1[0] == s2[j])
		{
			dp[0][j] = 1;
		}
	}
	for (int i = 1; i < m; i++)
	{
		for (int j = 1; j < n; j++)
		{
			if (s1[i] == s2[j])
			{
				dp[i][j] = dp[i - 1][j - 1] + 1;
			}
		}
	}
	return dp;
}

string lcst1(string s1, string s2)
{
	int m = s1.size();
	int n = s2.size();

	if (m == 0 || n == 0)return "";

	vector<vector<int>> dp = getdp(s1, s2);

	int end = 0;
	int maxa = 0;

	for (int i = 0; i < m; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if (dp[i][j] > maxa)
			{
				end = i;
				maxa = dp[i][j];
			}
		}
	}
	return s1.substr(end - maxa + 1, maxa);
}
string lcst2(string s1, string s2) 
{
	int m = s1.size();
	int n = s2.size();
	if (m == 0 || n == 0)return "";

	int row = 0; // 出发点的行号
	int col = n - 1; // 出发点的列号
	int max = 0;
	int end = 0;
	while (row < m) {
		int i = row;
		int j = col;
		int len = 0;
		// 向右下方移动的这一轮
		while (i < m && j < n) {
			if (s1[i] != s2[j]) {
				len = 0;
			}
			else {
				len++;
			}
			// len
			if (len > max) {
				end = i;
				max = len;
			}
			i++;
			j++;
		}
		if (col > 0) {
			col--;
		}
		else {
			row++;
		}
	}
	return s1.substr(end - max + 1, max);
}
题目六

在这里插入图片描述

// version 1: map+sort
class Node {
public:
    int time;
    string word;
    Node(int _time, string _word) {
        time = _time, word = _word;
    };
    bool operator < (const Node& obj) const {
        return time > obj.time || time == obj.time && word < obj.word;
    }
};
class Solution {
public:
    /**
     * @param words an array of string
     * @param k an integer
     * @return an array of string
     */
    vector<string> topKFrequentWords(vector<string>& words, int k) {
        int n = words.size();
        map<string, int> mp1;
        map<string, int>::iterator it1;
        for (int i = 0; i < n; ++i) {
            if (mp1.find(words[i]) == mp1.end())
                mp1[words[i]] = 1;
            else
                mp1[words[i]] += 1;
        }
        vector<Node> p;
        for (it1 = mp1.begin(); it1 != mp1.end(); it1++)
            p.push_back(Node(it1->second, it1->first));
        sort(p.begin(), p.end());
        vector<string> result;
        for (int i = 0; i < k; ++i)
            result.push_back(p[i].word);
        return result;
    }
};

可以使用哈希表加堆来进行操作

// version 2: map+heap
class Node1 {
public:
    string s;
    int cnt;
    Node1(const string s, int cnt)
        : s(s)
        , cnt(cnt)
    {}

    bool operator < (const Node1& rhs) const {
        return cnt < rhs.cnt ||
            (cnt == rhs.cnt && s > rhs.s);
    }
};
class Solution {
public:
    /**
     * @param words: an array of string
     * @param k: An integer
     * @return: an array of string
     */
    vector<string> topKFrequentWords(vector<string>& words, int k) {
        map<string, int> m;
        for (const string& i : words) {
            if (m.find(i) == m.end())
                m[i] = 1;
            else
                m[i]++;
        }

        priority_queue<Node1> heap;
        for (auto i = m.begin(); i != m.end(); i++)
            heap.push(Node1(i->first, i->second));

        vector<string> result;
        for (int i = 0; i < k; i++) {
            result.push_back(heap.top().s);
            heap.pop();
        }

        return result;
    }
};

题目七:

在这里插入图片描述

#include<iostream>
#include<set>
#include<map>
#include<vector>
using namespace std;

map<string, int> words;
class cmp {
public:
    bool operator () (const string& a, const string& b) {
        int a_count = words[a];
        int b_count = words[b];
        if (a_count != b_count)
            return a_count > b_count;
        return a < b;
    }
};

class TopK {
private:
    set<string, cmp> q;
    int k;
public:
    TopK(int k) {
        // initialize your data structure here
        this->k = k;
    }

    void add(string& word) {
        // Write your code here
        if (words.find(word) == words.end()) {
            words[word] = 1;
        }
        else {
            if (q.find(word) != q.end())
                q.erase(q.find(word));
            words[word] += 1;
        }
        q.insert(word);
        if (q.size() > k)
            q.erase(--q.end());
    }

    vector<string> topk() {
        // Write your code here
        vector<string> topk;
        set<string, cmp>::iterator it = q.begin();
        int i = 0;
        for (int i = 0; i < k && it != q.end(); ++i, ++it) {
            topk.push_back(*it);
        }
        return topk;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值