888. 公平的糖果交换;1185. 一周中的第几天;1089. 复写零;1184. 公交站间的距离;1275. 找出井字棋的获胜者;1177. 构建回文串检测;1146. 快照数组

  1. 公平的糖果交换
    爱丽丝和鲍勃有不同大小的糖果棒:A[i] 是爱丽丝拥有的第 i 块糖的大小,B[j] 是鲍勃拥有的第 j 块糖的大小。
    因为他们是朋友,所以他们想交换一个糖果棒,这样交换后,他们都有相同的糖果总量。(一个人拥有的糖果总量是他们拥有的糖果棒大小的总和。
    返回一个整数数组 ans,其中 ans[0] 是爱丽丝必须交换的糖果棒的大小,ans[1] 是 Bob 必须交换的糖果棒的大小。
    如果有多个答案,你可以返回其中任何一个。保证答案存在。
vector<int> fairCandySwap(vector<int>& A, vector<int>& B) {        
vector<int> res;        
int left = 0 , right = 0 , diff = 0;        
for(int i = 0 ; i < A.size() ; i++)            
	left += A[i];        
for(int i = 0 ; i < B.size() ; i++)            
	right += B[i];        
diff = left - right;               
for(int i = 0 ; i < A.size() ; i++)            
	for(int j = 0 ; j < B.size() ; j++)            
		{                
		if((A[i] - B[j])==diff/2)                    
			{                        
			res.push_back(A[i]);                        
			res.push_back(B[j]);                       
 			return res;                    
 			}            
		 }        
 return res;    
 }
  1. 一周中的第几天
    给你一个日期,请你设计一个算法来判断它是对应一周中的哪一天。
    输入为三个整数:day、month 和 year,分别表示日、月、年。
    您返回的结果必须是这几个值中的一个 {“Sunday”, “Monday”, “Tuesday”, “Wednesday”,“Thursday”, “Friday”, “Saturday”}。
 string dayOfTheWeek(int day, int month, int year) {        
 vector<string> res;        
 // 周日是第一天        
 res.push_back("Sunday");        
 res.push_back("Monday");        
 res.push_back("Tuesday");        
 res.push_back("Wednesday");        
 res.push_back("Thursday");        
 res.push_back("Friday");        
 res.push_back("Saturday");               
 if(month<3)        
 {            
 	month += 12;            
 	year--;        
 }        
 // 基姆拉尔森计算公式        
 return res[(day+2*month+3*(month+1)/5+year+year/4-year/100+year/400+1) % 7];    }
  1. 复写零
    给你一个长度固定的整数数组 arr,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。
    注意:请不要在超过该数组长度的位置写入元素。
    要求:请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。
    void duplicateZeros(vector<int>& arr) {        
    int cnt = 0;        
    for(int i = 0 ; i < arr.size() ; i++)        
    	{            
   		 if(arr[i]==0) cnt++;        
    	}        
    // 从后向前        
    for(int i = arr.size()-1 ; i > -1 ; i--)        
    	{            
   		 if(arr[i]==0)             
   		 {                
    			cnt--;                
    			if(i + cnt < arr.size()) arr[i+cnt] = 0;                 
  			if(i + cnt + 1< arr.size()) arr[i+cnt+1] = 0; // 复写
		}            
		else if(i + cnt < arr.size())                
			arr[i+cnt] = arr[i];        
	}           
}
  1. 公交站间的距离
    环形公交路线上有 n 个站,按次序从 0 到 n - 1 进行编号。我们已知每一对相邻公交站之间的距离,distance[i] 表示编号为 i 的车站和编号为(i + 1) % n 的车站之间的距离。
    环线上的公交车都可以按顺时针和逆时针的方向行驶。
    返回乘客从出发点 start 到目的地 destination 之间的最短距离。
int distanceBetweenBusStops(vector<int>& distance, int start, int destination) {        
int sum = 0 , temp = 0;        
for(int i = 0 ; i < distance.size() ; i++)        
	{            
		sum+=distance[i];        
	}        
int des = max(start , destination);        
for(int i = min(start , destination) ; i < des ; i++)        
	{            
		temp+=distance[i];        
	}        
return min(temp , sum - temp);
    }
  1. 找出井字棋的获胜者
    A 和 B 在一个 3 x 3 的网格上玩井字棋。
    井字棋游戏的规则如下:
    玩家轮流将棋子放在空方格 (" ") 上
    第一个玩家 A 总是用 “X” 作为棋子,而第二个玩家 B 总是用 “O” 作为棋子
    “X” 和 “O” 只能放在空方格中,而不能放在已经被占用的方格上
    只要有 3 个相同的(非空)棋子排成一条直线(行、列、对角线)时,游戏结束
    如果所有方块都放满棋子(不为空),游戏也会结束
    游戏结束后,棋子无法再进行任何移动
    给你一个数组 moves,其中每个元素是大小为 2 的另一个数组(元素分别对应网格的行和列),它按照 A 和 B 的行动顺序(先 A 后 B)记录了两人各自的棋子位置。
    如果游戏存在获胜者(A 或 B),就返回该游戏的获胜者;如果游戏以平局结束,则返回 “Draw”;如果仍会有行动(游戏未结束),则返回 “Pending”。
    你可以假设 moves 都 有效(遵循井字棋规则),网格最初是空的,A 将先行动。
public:    
string tictactoe(vector<vector<int>>& moves) {       
vector<vector<int>>wins = {            
{0, 1, 2}, // row            
{3, 4, 5},            
{6, 7, 8},            
{0, 3, 6}, // col            
{1, 4, 7},            
{2, 5, 8},            
{0, 4, 8}, // 对角线            
{2, 4, 6}        
};        
set<int> A , B ; //        
for(int i = 0 ; i < moves.size() ; i++)        
	{            
	int pos = moves[i][0]*3 + moves[i][1];            
	if(i%2==0) // A            
		{                
		A.insert(pos);                
		if(judge(A , wins))                    
			return "A";            
		}            
	else            
		{                
		B.insert(pos);                
		if(judge(B , wins))                    
			return "B";            
		}        
	}        
return moves.size()==9 ? "Draw" : "Pending";            
}
private:    
	bool judge(set<int> & S ,  vector<vector<int>>wins)    
{        
	for(auto win : wins)        
	{            
	bool flag = true;                
	for(auto temp : win) // 查找字母                
		{                    
		if(S.count(temp)==0) // 只要一个不存在就是假                    
			{                        
			flag = false;                        
			break;                    
			}                
		}                	
	if(flag)                    
	return true;        
	}        
return false;                
}
  1. 构建回文串检测
    给你一个字符串 s,请你对 s 的子串进行检测。
    每次检测,待检子串都可以表示为 queries[i] = [left, right, k]。我们可以 重新排列 子串 s[left], …, s[right],并从中选择 最多 k 项替换成任何小写英文字母。
    如果在上述检测过程中,子串可以变成回文形式的字符串,那么检测结果为 true。否则结果为 false。返回答案数组 answer[],其中 answer[i] 是第 i 个待检子串 queries[i] 的检测结果。
    注意:在替换时,子串中的每个字母都必须作为 独立的 项进行计数,也就是说,如果 s[left…right] = “aaa” 且 k = 2。我们只能替换其中的两个字母,另外,任何检测都不会修改原始字符串 s,可以认为每次检测都是独立的)。
 vector<bool> canMakePaliQueries(string s, vector<vector<int>>& queries) {       
 // 看题解         
 int cnt = 0;         
 int temp[s.size()];         
 for(int i = 0 ; i < s.size() ; i++)         
 	{              
 		int bit = s[i] - 'a';                 
		 cnt ^=(1<<bit);                
 		temp[i] = cnt;         
	 }        
 vector<bool> res;        
 int odd = 0;        
 for(auto querie : queries)        
 	{            
 		 odd = 0;            
		 int a = 0 , b = 0 , r = 0;            
		 if(querie[0]>0)                
 			 a = temp[querie[0]-1]; //必须减一 才是从 querie[0]--querie[1] 之间的数            
		 else                
			 a = 0;                   
		 b = temp[querie[1]];            
		 r = a^b;           
  while(r!=0)            
 	 {                
 		 if((r&1)==1)                
 		 {                    
  			odd++;                
 		 }                
 		 r>>=1;            
 	 }           
res.push_back(querie[2]>=odd/2);        
}        
   return res;
}
  1. 快照数组
    实现支持下列接口的「快照数组」- SnapshotArray:
    SnapshotArray(int length) - 初始化一个与指定长度相等的 类数组 的数据结构。初始时,每个元素都等于0.
    void set(index, val) - 会将指定索引 index 处的元素设置为 val。
    int snap() - 获取该数组的快照,并返回快照的编号 snap_id(快照号是调用 snap() 的总次数减去 1)。
    int get(index, snap_id) - 根据指定的 snap_id 选择快照,并返回该快照指定索引 index 的值。
 map<int , map<int ,int>> res;    
 SnapshotArray(int length) {            }    
 int cnt = 0;    
 void set(int index, int val) {        
 	if(res[index].size()==0) res[index][0] = 0;        
 	res[index][cnt] = val;   // 次数    
 	}
int snap() {        
	return cnt++;   // 次数    
	}   
int get(int index, int snap_id) {        
	if(res[index].size()==0) res[index][0] = 0;        // upper_bound 二分查找第一个大于这个数的值  然后减一 输出cval        
	return (--res[index].upper_bound(snap_id))->second ;     
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值