题目链接: Leetcode Weekly Contest 239
写在前面:
本次周赛只做出了第一道。
1、1848. Minimum Distance to the Target Element
难度:Easy
题目大意:
详见题意。
思路:
根据题意模拟即可。
代码
class Solution {
public int getMinDistance(int[] nums, int target, int start) {
int res=Integer.MAX_VALUE;
for(int i=0;i<nums.length;i++){
if(nums[i]==target){
res=Math.min(res,Math.abs(i-start));
}
}
return res;
}
}
2、1849. Splitting a String Into Descending Consecutive Values
难度:Medium
题目大意:
详见题意。
思路:
参考评论区大佬的思路和代码,dfs+剪枝。代码如果不太好理解的话可以举个例子来帮助理解。
代码
class Solution {
char[] nums;
int n;
public boolean splitString(String s) {
nums=s.toCharArray();
n=s.length();
return dfs(0,0,0);
}
public boolean dfs(int index,long prev,int cnt){
if(index==n){
return cnt>1;
}
long cur=0;
for(int i=index;i<n;i++){
cur=cur*10+nums[i]-'0';
if(cnt==0||cur==prev-1){//剪枝
if(dfs(i+1,cur,cnt+1)){
return true;
}
}
}
return false;
}
}
3、1850. Minimum Adjacent Swaps to Reach the Kth Smallest Number
难度:Medium
题目大意:
详见题目。
思路:
本题是Leetcode 31. Next Permutation的扩展,求最小操作次数的思路参考高赞回答。
代码
class Solution {
public int getMinSwaps(String num, int k) {
int n=num.length();
int[] nums=new int[n];
int[] originalNum=new int[n];
for(int i=0;i<n;i++){
nums[i]=num.charAt(i)-'0';
originalNum[i]=num.charAt(i)-'0';
}
while(k-->0){
nextPermutation(nums);
}
return stepCount(originalNum,nums);
}
public void nextPermutation(int[] nums) {
int i=nums.length-2;
while(i>=0&&nums[i]>=nums[i+1]){
i--;
}
if(i>=0){
int j=nums.length-1;
while(nums[j]<=nums[i]){
j--;
}
swap(nums,i,j);
}
reverse(nums,i+1);
}
public void reverse(int[] nums,int start){
int end=nums.length-1;
while(start<end){
swap(nums,start,end);
start++;
end--;
}
}
public void swap(int[] nums,int i,int j){
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
public int stepCount(int[] nums1,int[] nums2){
//统计至少经过多少次相邻元素的交换才能使得两个数组相等
int count=0;
int i=0,j=0;
while(i<nums1.length){
j=i;
while(nums2[j]!=nums1[i]){
j++;
}
while(j>i){
swap(nums2,j,j-1);
j--;
count++;
}
i++;
}
return count;
}
}
4、1851. Minimum Interval to Include Each Query
难度:Hard
题目大意:
详见题目。
思路
参考高赞回答,对区间和要查找的数进行排序,然后使用优先队列来寻找满足题意的最小区间。
代码
class Solution {
public int[] minInterval(int[][] intervals, int[] queries) {
int n=intervals.length;
Arrays.sort(intervals,(a,b)->a[0]==b[0]?(a[1]-a[0])-(b[1]-b[0]):a[0]-b[0]);
int[][] query=new int[queries.length][2];
for(int i=0;i<queries.length;i++){
query[i][0]=queries[i];
query[i][1]=i;
}
Arrays.sort(query,(a,b)->a[0]-b[0]);
int[] res=new int[query.length];
Queue<int[]> pq=new PriorityQueue<>((a,b)->a[0]-b[0]);//按区间长度排序
int j=0;
for(int i=0;i<query.length;i++){
while(j<n&&intervals[j][0]<=query[i][0]){
int l=intervals[j][0],r=intervals[j][1];
pq.offer(new int[]{r-l+1,r});
j++;
}
while(!pq.isEmpty()&&pq.peek()[1]<query[i][0]){
pq.poll();//将不满足的区间弹出
}
if(pq.isEmpty()){
res[query[i][1]]=-1;
}
else{
res[query[i][1]]=pq.peek()[0];
}
}
return res;
}
}