1417. 重新格式化字符串
签到题,没什么好说的,比赛的时候写的复杂了一些。
class Solution {
public String reformat(String s) {
char [] arr = s.toCharArray();
ArrayList<Character> cs1 = new ArrayList<Character>();
ArrayList<Character> cs2 = new ArrayList<Character>();
int counter1 = 0;
int counter2 = 0;
for(int i=0;i<s.length();i++)
{
if(arr[i]>='0'&&arr[i]<='9')
{
counter1++;
cs1.add(arr[i]);
}
else
{
counter2++;
cs2.add(arr[i]);
}
}
if(Math.abs(counter1-counter2)>1)
return "";
String res = "";
if(counter1>counter2)
{
res = String.valueOf(cs1.get(0));
int i=1;
int j=0;
while(i<cs1.size()&&j<cs2.size())
{
res = res + cs2.get(j);
res = res + cs1.get(i);
i++;
j++;
}
}
else if(counter1<counter2)
{
res = String.valueOf(cs2.get(0));
int i=0;
int j=1;
while(i<cs1.size()&&j<cs2.size())
{
res = res + cs1.get(i);
res = res + cs2.get(j);
i++;
j++;
}
}
else
{
res ="";
int i=0;
int j=0;
while(i<cs1.size()&&j<cs2.size())
{
res = res + cs1.get(i);
res = res + cs2.get(j);
i++;
j++;
}
}
return res;
}
}
1418. 点菜展示表
这个题目主要考察的是数据结构和编写代码的能力,我一步步做的,没有理解的太清晰,所以花了不少时间。
我是这么想的,首先排除吃饭的客人这个属性,这个属性没有用,我们关注的就是食物和点餐的餐桌序号。
第一遍扫描,我们确定所有的食物列表,按照字母排序,这样我们就可以用一个int数组去储存每种食物出现的次数。
第二遍扫描的时候,我们就把出现的食物和点餐桌号真正关联起来,同样是用一个hashmap,key是餐桌,value是一个int数组。
最后,我们把结果按照规定的方式输出。
class Solution {
public List<List<String>> displayTable(List<List<String>> orders) {
ArrayList<List<String>> res = new ArrayList<List<String>>();
Map<String, Integer> map1 = new HashMap<String, Integer>();
Map<String, Integer[]> map2 = new HashMap<String, Integer[]>();
Set<String> items = new HashSet<String>();
for(List<String> ss:orders)
{
if(!items.contains(ss.get(2)))
{
items.add(ss.get(2));
}
}
String[] is = new String[items.size()];
int counter = 0;
for(String s:items)
{
is[counter] = s;
counter++;
}
Arrays.sort(is);
ArrayList<String> table = new ArrayList<String>();
table.add("Table");
for(int i=0;i<is.length;i++)
{
map1.put(is[i],i);
table.add(is[i]);
}
res.add(table);
for(List<String> ss:orders)
{
String tableNumber = ss.get(1);
String itemName = ss.get(2);
if(map2.containsKey(tableNumber))
{
Integer[] tmp = map2.get(tableNumber);
int index = map1.get(itemName);
tmp[index]++;
map2.put(tableNumber,tmp);
}
else
{
Integer[] tmp = new Integer[is.length];
for(int i=0;i<is.length;i++)
{
tmp[i] = 0;
}
int index = map1.get(itemName);
tmp[index]++;
map2.put(tableNumber,tmp);
}
}
Set set=map2.keySet();
Object[] arr=set.toArray();
int[] sss = new int[arr.length];
for(int i=0;i<arr.length;i++)
{
int keyS = Integer.valueOf(arr[i].toString());
sss[i] = keyS;
}
Arrays.sort(sss);
for(Integer m:sss){
String keyS = String.valueOf(m);
ArrayList<String> element = new ArrayList<String>();
element.add(keyS);
Integer[] ints = map2.get(keyS);
for(Integer i:ints)
{
element.add(String.valueOf(i));
}
res.add(element);
}
return res;
}
}
1419. 数青蛙
这个题就是一看到题目下手太快了,没有注意到数据规模,导致方法不对,超时。
我最开始看这个题目,感觉简单啊,我直接模拟,第一只青蛙叫完,第二只青蛙再叫,模拟完就出结果,但是这样一定会超时,当时发现了可能的解法之后,已经没时间改了。
这个题应该怎么做呢?这里面涉及到对数的统计。我们只扫描一遍,我们想象一下,有一只青蛙叫了一次又一次croak,当它找到cro的时候,要找a,这个时候却出现了k,那么再多的青蛙,也不可能完成这个任务,如果再遇到一个o,那么这个o肯定要交给其他的青蛙解决。
那么我们可以扫描一遍,记录每个字母出现的次数,每个字母出现次数的最大值就是答案,当遇到不可能完成的任务的时候,返回-1,当扫描完一遍croak的时候要把count每个-1,因为这只青蛙可以继续croak。
class Solution {
public int minNumberOfFrogs(String croakOfFrogs) {
char[] chars = croakOfFrogs.toCharArray();
if (chars.length % 5 != 0) {
return -1;
}
Map<Character, Integer> map = new HashMap<>();
map.put('c', 0);
map.put('r', 1);
map.put('o', 2);
map.put('a', 3);
map.put('k', 4);
int[] counts = new int[5];
int result = 0;
for (char c : chars) {
int idx = map.get(c);
++counts[idx];
result = Math.max(result, counts[idx]);
for (int i = 0; i < idx; ++i) {
if (counts[i] < counts[idx]) {
return -1;
}
}
if (idx == 4) {
for (int i = 0; i < 5; ++i) {
--counts[i];
}
}
}
return result;
}
}
1420. 生成数组
这个题好像之前做过类似的,还是要观察数字的性质,显然是一个动态规划,dp[n][i][k]代表长度为n,最大值为i,cost为k的情况。但是这个动态规划怎么分类写状态转移方程呢?我们还是要观察这个cost是如何变动的。其实很简单,就是分为两大类,当前长度是n-1,我们再添加一个元素,如果最后一个值是最大值,比前面的值都大,那么cost一定会加1,如果不是最大值,那么cost则不变,所以状态转移方程可以分成两部分写,一部分是添加的值是最大值,那么最大值是1,...,i-1,cost是k-1的情况我们都可以累加进dp[n][i][k],如果不是最大值,则1-i都可选,就是i*dp[n-1][i][k]。
class Solution {
int mod = 1000000007;
public int numOfArrays(int n, int m, int k) {
int[][][] dp = new int[n+1][m+1][k+1];
for(int i=0;i<=n;i++)
{
for(int ii=0;ii<=m;ii++)
{
for(int iii=0;iii<=k;iii++)
{
dp[i][ii][iii] = -1;
}
}
}
int res = 0;
for(int i=1;i<m+1;i++)
{
res = res + fuc(dp,n,i,k);
res %= mod;
}
return res;
}
public int fuc(int[][][] dp, int n, int i, int k)
{
if(dp[n][i][k]!=-1)
return dp[n][i][k];
if(n==0||i==0||k==0)
{
dp[n][i][k] = 0;
return 0;
}
if(n==1&&k==1)
{
dp[n][i][k] = 1;
return 1;
}
int res = 0;
for(int j=1;j<i;j++)
{
res = res + fuc(dp,n-1,j,k-1);
res %= mod;
}
res = res + i * fuc(dp,n-1,i,k);
res %= mod;
dp[n][i][k] = res;
return res;
}
}