题目链接: Leetcode Weekly Contest 226
写在前面:
本次周赛又是尴尬只做了第一题,寒假得多刷题了。
1、1742. Maximum Number of Balls in a Box
难度:Easy
题目大意:
将小球按照一定规则放入特定的盒子里,求单个盒子中小球数量的最大值。
思路:
按题目要求进行模拟即可。
代码
class Solution {
public int countBalls(int lowLimit, int highLimit) {
//箱子编号最大值为9+9+9+9+9=45(球的编号为99999)
int[] box=new int[46];//下标从0~45
for(int i=lowLimit;i<=highLimit;i++){
int sum=0;//各个位上的数字之和
int a=i;//把i的值赋给a,对i直接运算会导致i的值发生变化,影响for循环
while(a>0){
sum+=(a%10);
a/=10;
}
box[sum]++;
}
int res=0;
for(int i=1;i<46;i++){
if(box[i]>res){
res=box[i];
}
}
return res;
}
}
2、1743. Restore the Array From Adjacent Pairs
难度:Medium
题目大意:
给出若干个长度为2的子数组,子数组内两个数在原数组中是相邻的,要求根据这些子数组恢复出原数组。
思路:
参考高赞回答,用map存储各个元素的相邻元素,如何遍历,只有一个邻居的元素为原数组的第一个元素,然后根据相邻元素的信息依次递推出后面的元素。
代码
class Solution {
public int[] restoreArray(int[][] pairs) {
Map<Integer,List<Integer>> map=new HashMap<Integer,List<Integer>>();
for(int[] arr:pairs){//用map存储各个元素的相邻元素
if(!map.containsKey(arr[0])){//arr[1]是arr[0]的相邻元素
List<Integer> temp=new ArrayList<Integer>();
temp.add(arr[1]);
map.put(arr[0],temp);
}
else{
map.get(arr[0]).add(arr[1]);
}
if(!map.containsKey(arr[1])){//arr[0]是arr[1]的相邻元素
List<Integer> temp=new ArrayList<Integer>();
temp.add(arr[0]);
map.put(arr[1],temp);
}
else{
map.get(arr[1]).add(arr[0]);
}
}
int start=0;//表示第一个元素
for(int key:map.keySet()){//寻找第一个元素
if(map.get(key).size()==1){//只有一个相邻元素
start=key;
break;
}
}
int len=pairs.length;
int[] res=new int[len+1];
Set<Integer> set=new HashSet<Integer>();//用来存储遍历过的元素
int count=0;
res[count++]=start;
set.add(start);
for(int i=1;i<=len;i++){
List<Integer> list=map.get(res[i-1]);
int value=0;//下一个元素
if(list.size()==1){
value=list.get(0);
}
else{
if(set.contains(list.get(0))){
value=list.get(1);
}
else{
value=list.get(0);
}
}
res[count++]=value;
set.add(value);
}
return res;
}
}
3、1744. Can You Eat Your Favorite Candy on Your Favorite Day?
难度:Medium
题目大意:
判断能否在特定的某一天吃到最喜欢的某种糖果。
思路:
题目比较长,需要花一定时间理解,理解之后难度不大。关键在于两个临界条件的判断,本题还需要主要天数是从第0天开始算的,同时要注意数据类型和范围的问题,用int会溢出。
代码
class Solution {
public boolean[] canEat(int[] candiesCount, int[][] queries) {
int n=queries.length;
int len=candiesCount.length;
long[] prefixSum=new long[len+1];//前缀和
prefixSum[0]=0;
for(int i=1;i<len+1;i++){
prefixSum[i]=prefixSum[i-1]+candiesCount[i-1];//prefixSum[i]表示candiesCount[i]前面所有元素之和
}
boolean[] ans=new boolean[n];
for(int i=0;i<n;i++){
int type=queries[i][0];
long day=queries[i][1];
int cap=queries[i][2];
if(prefixSum[type]-day*cap>=cap){//吃不完前面的糖果,注意有一种情况是一天之内可能吃多种糖果,所以是>=cap而不是>=0
ans[i]=false;
}
else if(prefixSum[type+1]-1<day){//每天吃一个都撑不到第day天(注意有第0天)
ans[i]=false;
}
else{
ans[i]=true;
}
}
return ans;
}
}
4、1745. Palindrome Partitioning IV
难度:Hard
题目大意:
很经典的一道题。判断能否将字符串分割成3个子字符串,使得这三个子字符串都是回文串。
思路
因为字符串长度在2000以内,暴力求解就能过。判断字符串是否为回文串如果一个字符一个字符地进行比较会超时,用DP打表来进行判断。
代码
class Solution {
public boolean checkPartitioning(String s) {
int n=s.length();
char[] arr=s.toCharArray();
boolean[][] dp=new boolean[n][n];//dp[i][j]表示s[i,j]为回文字符串
for(int i=n-1;i>=0;i--){
for(int j=i;j<n;j++){
if(j==i){
dp[i][j]=true;
}
else if(j-i==1){
dp[i][j]=(arr[i]==arr[j]);
}
else{//字符串长度大于2
dp[i][j]=(arr[i]==arr[j])&&dp[i+1][j-1];
//因为dp[i][j]与dp[i+1][j-1]有关,所有i要从大到小遍历,j要从小到大遍历
}
}
}
for(int l=1;l<=n-2;l++){
for(int r=l;r<n-1;r++){
if(dp[0][l-1]&&dp[l][r]&&dp[r+1][n-1]){
return true;
}
}
}
return false;
}
}