思路:做法很多,我的方法是定义两个队列分别存数字和字符,然后在满足题目要求能够格式化的情况下穿插着加入答案即可。
class Solution {
StringBuilder str;
public String reformat(String s) {
if(s.length()<=1) return s;
int n=s.length();
str=new StringBuilder();
Queue<Character> q1=new LinkedList<>();
Queue<Character> q2=new LinkedList<>();
for(int i=0;i<n;i++) {
if(s.charAt(i)>='0' && s.charAt(i)<='9') q1.add(s.charAt(i));
else q2.add(s.charAt(i));
}
if(Math.abs(q1.size()-q2.size())>1) return "";
if(q1.size()>q2.size()) work(q1,q2);
else work(q2,q1);
return str.toString();
}
private void work(Queue<Character> q1,Queue<Character> q2) {
while(!q1.isEmpty()) {
str.append(q1.poll());
if(!q2.isEmpty())
str.append(q2.poll());
}
}
}
思路:数据结构的考察,比较中规中矩的题目,没有需要思考的地方,无非是每个人存储信息的方式不同。我采用map里嵌套map的形式存储每个桌对应的id和该桌点的菜以及对应的数量。
class Solution {
public List<List<String>> displayTable(List<List<String>> orders) {
List<String> res=new ArrayList<>();
List<String> caiList=new ArrayList<>();
Map<String,Integer> flag=new HashMap<>();
List<List<String>> ans=new ArrayList<>();
Map<String,Map<String,Integer>> peoples=new HashMap<>();
for(int i=0;i<orders.size();i++) {
String num=orders.get(i).get(1);
String cai=orders.get(i).get(2);
if(!peoples.containsKey(num))
peoples.put(num, new HashMap<>());
peoples.get(num).put(cai, peoples.get(num).getOrDefault(cai, 0)+1);
if(flag.containsKey(cai))
continue;
flag.put(cai, caiList.size());
caiList.add(cai);
}
List<Integer> ids=new ArrayList<>();
for(String id : peoples.keySet())
ids.add(Integer.valueOf(id));
int len=caiList.size();
String[] caiNames=new String[len];
for(int i=0;i<len;i++)
caiNames[i]=caiList.get(i);
Collections.sort(ids);
Arrays.parallelSort(caiNames);
res.add("Table");
for(int i=0;i<len;i++)
res.add(caiNames[i]);
ans.add(new ArrayList<>(res));
for(int i=0;i<ids.size();i++) {
res.clear();
String id=String.valueOf(ids.get(i));
res.add(id);
for(int j=0;j<len;j++)
res.add(String.valueOf(peoples.get(id).getOrDefault(caiNames[j], 0)));
ans.add(new ArrayList<>(res));
}
return ans;
}
}
思路:‘croak’是顺序固定的,因此我们可以线性遍历,当遇到k前边没有c时返回-1,当遇到o前边没有r时返回-1,....,以此类推。并在该过程中记录的当前c的最大值一定是所要求的最小值。
class Solution {
public int minNumberOfFrogs(String croakOfFrogs) {
int ans=0;
int n=croakOfFrogs.length();
if(n%5!=0) return -1;
int num=0;
int[] nums=new int[5];
for(int i=0;i<n;i++) {
char c=croakOfFrogs.charAt(i);
if(c=='c') {
num++;
nums[0]++;
}
else if(c=='r') {
if(nums[0]<=0) return -1;
nums[0]--; nums[1]++;
}
else if(c=='o') {
if(nums[1]<=0) return -1;
nums[1]--; nums[2]++;
}
else if(c=='a') {
if(nums[2]<=0) return -1;
nums[2]--; nums[3]++;
}
else {
if(nums[3]<=0) return -1;
num--;
}
ans=Math.max(ans, num);
}
return ans;
}
}
思路:动态规划,定义dp[i][j][k]:表示组成了i个数,最大数为j并且最长严格递增序列长度为k的方案数。
class Solution {
private int mod=1000000007;
public int numOfArrays(int n, int m, int k) {
long[][][] dp=new long[n+1][m+1][k+1];
for(int i=1;i<=m;i++)
dp[1][i][1]=1;
for(int i=2;i<=n;i++)
for(int h=1;h<=k;h++) {
long sm=0;
for(int j=1;j<=m;j++) {
dp[i][j][h]=1L*j*dp[i-1][j][h]%mod;
dp[i][j][h]=(dp[i][j][h]+sm)%mod;
sm=(sm+dp[i-1][j][h-1])%mod;
}
}
long ans=0;
for(int i=1;i<=m;i++)
ans=(ans+dp[n][i][k])%mod;
return (int)ans;
}
}