【c++笔试强训】(第二十篇)

目录

重排字符串(贪⼼+构造)

题目解析

讲解算法原理

编写代码

乒乓球筐(哈希)

题目解析

讲解算法原理

编写代码


重排字符串(贪⼼+构造)

题目解析

1.题目链接:登录—专业IT笔试面试备考平台_牛客网

2.题目描述

题目描述

小红拿到了一个只由小写字母组成的字符串。她准备把这个字符串重排(只改变字母的顺序,不改变数量)
重排后小红想让新字符串不包含任意两个相同的相邻字母。
你能帮帮她吗?

输入描述:

第一行一个正整数 nnn ,代表字符串的长度。 (1≤n≤105)(1 \leq n \leq 10^5)(1≤n≤105)
第二行为一个长度为 nnn 的、只由小写字母组成的字符串。

输出描述:

如果可以完成重排,请在第一行输出一个“yes”,第二行输出重排后的字符串。如果有多个正解,输出任意即可。
如果不能重排,则直接输出“no”

示例1

输入

5 aaaaa

5
aaaaa

输出

no

no

示例2

输入

7 aabbccc

7
aabbccc

输出

yes cabcabc

yes
cabcabc

讲解算法原理

解法:
算法思路:

⼒扣有⼀道《距离相等的条形码》和这道题是差不多滴~

编写代码

c++算法代码:

#include <iostream>
using namespace std;
const int N = 100010;
int n;
char s[N];
char ret[N];
int main()
{
 cin >> n >> s;
 
 int hash[26] = { 0 }; // 统计每个字符的频次 int maxIndex, maxCount = 0; for(int i = 0; i < n; i++) {
 if(maxCount < ++hash[s[i] - 'a'])
 {
 maxCount = hash[s[i] - 'a']; maxIndex = s[i] - 'a'; }
 }
 
 if(maxCount > (n + 1) / 2) cout << "no" << endl; else
 {
 cout << "yes" << endl; int index = 0;
 // 先去摆放出现次数最多的 while(maxCount--) {
 ret[index] = maxIndex + 'a'; index += 2;
 }
 // 处理剩下的
 for(int i = 0; i < 26; i++)
 {
 if(hash[i] && i != maxIndex)
 {
 while(hash[i]--)
 {
 if(index >= n) index = 1; ret[index] = i + 'a'; index += 2;
 }
 }
 }
 // 打印结果
 for(int i = 0; i < n; i++) cout << ret[i]; cout << endl;
 }
 
 return 0;
}

java算法代码:

import java.util.*;
public class Main
{
 public static void main(String[] args)
 {
 Scanner in = new Scanner(System.in); int n = in.nextInt(); char[] s = in.next().toCharArray();  char maxChar = '0'; int maxCount = 0; int[] hash = new int[26];
 // 找出现次数最多的字符以及次数 for(int i = 0; i < n; i++) {
 char ch = s[i]; if(++hash[ch - 'a'] > maxCount) { maxChar = ch; maxCount = hash[ch - 'a']; }
 }
 
 // 判断是否能重排
 if(maxCount > (n + 1) / 2)
 {
 System.out.println("no");
 }
 else
 {
 System.out.println("yes"); char[] ret = new char[n]; int i = 0; // 重新排列
 // 1. 先处理出现次数最多的字符 while(maxCount-- != 0) {
 ret[i] = maxChar; i += 2;
 }
 // 2. 处理剩下的字符
 for(int j = 0; j < 26; j++)
 {
 if(hash[j] != 0 && (char)(j + 'a') != maxChar)
 {
 while(hash[j]-- != 0)
 { if(i >= n) {
 i = 1;
 } ret[i] = (char)(j + 'a'); i += 2; } }
 }
 for(int j = 0; j < n; j++)
 {
 System.out.print(ret[j]);
 }
 }
 }
}

 

乒乓球筐(哈希)

题目解析

1.题目链接:乒乓球筐__牛客网

2.题目描述

nowcoder有两盒(A、B)乒乓球,有红双喜的、有亚力亚的……现在他需要判别A盒是否包含了B盒中所有的种类,并且每种球的数量不少于B盒中的数量,该怎么办呢?

输入描述:

输入有多组数据。
每组数据包含两个字符串A、B,代表A盒与B盒中的乒乓球,每个乒乓球用一个大写字母表示,即相同类型的乒乓球为相同的大写字母。
字符串长度不大于10000。

输出描述:

每一组输入对应一行输出:如果B盒中所有球的类型在A中都有,并且每种球的数量都不大于A,则输出“Yes”;否则输出“No”。

示例1

输入

ABCDFYE CDE<br/>ABCDGEAS CDECDE

输出

Yes<br/>No

讲解算法原理

解法:
算法思路:

简单查询题⽬,可以⽤哈希表帮助我们解决。

编写代码

c++算法代码:

#include <iostream>
#include <string>
using namespace std;
int main()
{
 string s1, s2;
 while(cin >> s1 >> s2) // 未知组数的输⼊ {
 int hash[26] = { 0 }; for(auto ch : s1) hash[ch - 'A']++; bool ret = true; for(auto ch : s2) { if(--hash[ch - 'A'] < 0) { ret = false; break;
 }
 }
 cout << (ret ? "Yes" : "No") << endl;
 }
 return 0;
}

java算法代码:

import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main
{ 
 public static void main(String[] args) 
 {
 Scanner in = new Scanner(System.in); while(in.hasNext()) // 未知组数的输⼊ {
 char[] s1 = in.next().toCharArray(); char[] s2 = in.next().toCharArray(); int[] hash = new int[26];
 for(int i = 0; i < s1.length; i++)
 {
 hash[s1[i] - 'A']++;
 }
 boolean ret = true; for(int i = 0; i < s2.length; i++) { if(--hash[s2[i] - 'A'] < 0) { ret = false; break; }
 }
 System.out.println(ret ? "Yes" : "No");
 }
 }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值