LeetCode156周周赛

赛题链接:https://leetcode-cn.com/contest/weekly-contest-156

赛题一:独一无二的出现次数

给你一个整数数组 arr,请你帮忙统计数组中每个数的出现次数。如果每个数的出现次数都是独一无二的,就返回 true;否则返回 false。

  1. 对arr排序
  2. 用两个迭代器统计各元素出现的次数,并记录在num中
  3. 对num排序
  4. 检查num中元素是否都是独一无二的
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
class Solution {
	
public:
    bool uniqueOccurrences(vector<int>& arr) {
    	vector<int> num;//用于记录各个数出现的次数
		vector<int>::iterator it;
		vector<int>::iterator im;
		sort(arr.begin(),arr.end());
		int count=0;
		it=arr.begin();//排序 
		for(im=it;im<arr.end();im++){
			if(*it==*im){//如果元素相同,count累计加一 
				count++;
			}
			else if(*it!=*im){//如果元素不同,将前一元素的统计次数压入。并让it指向新的元素。count记当前元素次数为1。 
				num.push_back(count);
				it=im;
				count=1;
			}
			if(im==arr.end()-1){//im扫描到最后一个元素,压入当前元素统计次数count。 
				num.push_back(count);
			}
		}
		//判断各个数的出现次数是否是独一无二的 
		sort(num.begin(),num.end());
		for(it=num.begin();it+1<num.end();it++){
			if(*it==*(it+1)){
				return false;
			}
		}
		return true;    
    }
};

int main()
{
	Solution my;
	vector<int> myv;
	myv.push_back(1);
	myv.push_back(2);
	cout<<my.uniqueOccurrences(myv);
	
	return 0;
}

赛题二:尽可能使字符串相等

给你两个长度相同的字符串,s 和 t。将 s 中的第 i 个字符变到 t 中的第 i 个字符需要 |s[i] - t[i]| 的开销(开销可能为 0),也就是两个字符的 ASCII 码值的差的绝对值。用于变更字符串的最大预算是 maxCost。在转化字符串时,总开销应当小于等于该预算,这也意味着字符串的转化可能是不完全的。如果你可以将 s 的子字符串转化为它在 t 中对应的子字符串,则返回可以转化的最大长度。如果 s 中没有子字符串可以转化成 t 中对应的子字符串,则返回 0。

  1. 记录两个字符串对应ASCII码的差值。
  2. 用贪心的思想,从某一下标开始往后累加差值,直到大于maxCost。记录这个累加的子字符串长度。
  3. 改变上述的下标,从头至尾。
#include<iostream>
#include<string>
#include<algorithm>
#include<math.h>
using namespace std;
class Solution {
	string s,t;
	int maxCost;
public:
    int equalSubstring(string s, string t, int maxCost) {
    	int count=maxCost;
    	int sum=0;
		int cnt[s.length()];//cnt记录两字符串对应的ASCII码差值 
		int l=0;//能转化的最大长度
		for(int i=0;i<s.length();i++){
			cnt[i]=abs(int(s[i]-t[i]));
//			cout<<cnt[i]<<" ";
		}
		for(int i=0;i<s.length();i++){
			int temp=0;//从当前字符对应差值开始加和次数的临时值,也即对应满足条件的子字符串的长度 
			sum=0;
			for(int j=i;j<s.length();j++){
				sum+=cnt[j];
				if(sum>count){
					break;
				}
				temp++;
			}
//			cout<<"k:"<<k<<endl;
			l=max(temp,l);
		}   
		return l;
    }
};
//测试 
int main()
{
	Solution my;
	cout<<my.equalSubstring("krpgjbjjznpzdfy","nxargkbydxmsgby",14);

	return 0;
}

赛题三

给你一个字符串 s,「k 倍重复项删除操作」将会从 s 中选择 k 个相邻且相等的字母,并删除它们,使被删去的字符串的左侧和右侧连在一起。你需要对 s 重复进行无限次这样的删除操作,直到无法继续为止。在执行完所有删除操作后,返回最终得到的字符串。(本题答案保证唯一)

  1. 判断当前字符串是否有重复k倍的字符(函数isok())
  2. 在确定有上述的情况下,找到重复字符的第一个下标
  3. 删去重复字符
#include<iostream>
#include<string>
#include<algorithm>
#include<math.h>
using namespace std;
class Solution {
public:
	bool isok(string str,int k)//判断字符串是否符合继续的条件 
	{
		int i=0;//指向str的首部
		for(i=0;i+2<str.length();i++){
			bool is=0;
			for(int j=0;j<k;j++){
				if(str[i]!=str[i+j]){
					is=1;
					break;
				}		
			}
			if(!is){
				return true;
			}
		}
		return false; 
	}
    string removeDuplicates(string s, int k) {
//    	cout<<s<<endl;
        while(isok(s,k)){
//        	cout<<isok(s,k)<<endl;
        	for(int i=0;i+2<s.length();i++){
        		bool is=0;
				for(int j=0;j<k;j++){
					if(s[i]!=s[i+j]){
						is=1;
						break;
					}
				}
				if(!is){
					s.erase(i,k);//删去 
				}
			}
		}
		return s; 
    }
};
int main()
{
	Solution my;
	cout<<my.removeDuplicates("pbbcggttciiippooaais",2);
	
	return 0;
}

赛题四 :穿过迷宫的最少移动次数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值