别再做AI工具搬运工!智能资产整合必须在Q3完成的4个技术卡点,否则明年系统将批量过期
2026/6/5 2:45:59
给你一个字符串s和一个字符c,其中c在s中至少出现一次。
返回一个整数数组answer,其中answer[i]是字符串s中下标i处的字符到最近的字符c的最短距离。
两个下标i和j之间的距离为abs(i - j)。
示例:
输入: s = "loveleetcode", c = "e" 输出: [3,2,1,0,1,0,0,1,2,2,1,0] 解释: 字符 'e' 在下标 3、5、6、11 处出现。 对于下标 0,最近的 'e' 在下标 3,距离为 |0-3| = 3。 对于下标 1,最近的 'e' 在下标 3,距离为 |1-3| = 2。 ...核心:
方法:
classSolution{/** * 使用两次遍历计算每个字符到最近目标字符的最短距离 * * @param s 输入字符串 * @param c 目标字符 * @return 每个位置到最近c的最短距离数组 */publicint[]shortestToChar(Strings,charc){intn=s.length();int[]result=newint[n];// 初始化为一个很大的值(大于可能的最大距离)// 最大距离不会超过n,所以用n作为初始值for(inti=0;i<n;i++){result[i]=n;}// 第一次遍历:从左到右,计算到左边最近c的距离intprev=-n;// 记录上一个c的位置,初始化为-n确保第一次更新for(inti=0;i<n;i++){if(s.charAt(i)==c){prev=i;}result[i]=Math.min(result[i],i-prev);}// 第二次遍历:从右到左,计算到右边最近c的距离prev=2*n;// 记录下一个c的位置,初始化为2*n确保第一次更新for(inti=n-1;i>=0;i--){if(s.charAt(i)==c){prev=i;}result[i]=Math.min(result[i],prev-i);}returnresult;}}importjava.util.*;classSolution{/** * 先预处理所有目标字符的位置,然后对每个位置二分查找最近的位置 */publicint[]shortestToChar(Strings,charc){// 预处理:找到所有c的位置List<Integer>positions=newArrayList<>();for(inti=0;i<s.length();i++){if(s.charAt(i)==c){positions.add(i);}}int[]result=newint[s.length()];// 对每个位置,找到最近的cfor(inti=0;i<s.length();i++){result[i]=findMinDistance(positions,i);}returnresult;}/** * 在有序位置列表中找到距离target最近的位置 */privateintfindMinDistance(List<Integer>positions,inttarget){// 二分查找插入位置intleft=0,right=positions.size();while(left<right){intmid=left+(right-left)/2;if(positions.get(mid)<target){left=mid+1;}else{right=mid;}}intminDist=Integer.MAX_VALUE;// 检查left位置(第一个>=target的位置)if(left<positions.size()){minDist=Math.min(minDist,positions.get(left)-target);}// 检查left-1位置(最后一个<target的位置)if(left>0){minDist=Math.min(minDist,target-positions.get(left-1));}returnminDist;}}classSolution{/** * 暴力:对每个位置遍历整个字符串 */publicint[]shortestToChar(Strings,charc){intn=s.length();int[]result=newint[n];for(inti=0;i<n;i++){intminDist=n;// 最大可能距离for(intj=0;j<n;j++){if(s.charAt(j)==c){minDist=Math.min(minDist,Math.abs(i-j));}}result[i]=minDist;}returnresult;}}时间复杂度:
空间复杂度:
字符e的位置:[3, 5, 6, 11]
两次遍历:
第一次遍历(左到右):
中间结果:[12,13,14,0,1,0,0,1,2,3,4,0]
第二次遍历(右到左):
最终结果:[3,2,1,0,1,0,0,1,2,2,1,0]
publicstaticvoidmain(String[]args){Solutionsolution=newSolution();// 测试用例1:标准示例int[]result1=solution.shortestToChar("loveleetcode",'e');System.out.println("Test 1: "+Arrays.toString(result1));// [3,2,1,0,1,0,0,1,2,2,1,0]// 测试用例2:目标字符在开头int[]result2=solution.shortestToChar("aaab",'b');System.out.println("Test 2: "+Arrays.toString(result2));// [3,2,1,0]// 测试用例3:目标字符在结尾int[]result3=solution.shortestToChar("baaa",'b');System.out.println("Test 3: "+Arrays.toString(result3));// [0,1,2,3]// 测试用例4:所有字符都是目标字符int[]result4=solution.shortestToChar("eeee",'e');System.out.println("Test 4: "+Arrays.toString(result4));// [0,0,0,0]// 测试用例5:只有一个目标字符int[]result5=solution.shortestToChar("abcdefg",'d');System.out.println("Test 5: "+Arrays.toString(result5));// [3,2,1,0,1,2,3]// 测试用例6:单字符字符串int[]result6=solution.shortestToChar("a",'a');System.out.println("Test 6: "+Arrays.toString(result6));// [0]// 测试用例7:两个字符int[]result7=solution.shortestToChar("ab",'b');System.out.println("Test 7: "+Arrays.toString(result7));// [1,0]// 测试用例8:目标字符多次出现int[]result8=solution.shortestToChar("abccba",'c');System.out.println("Test 8: "+Arrays.toString(result8));// [2,1,0,0,1,2]// 测试用例9:长字符串int[]result9=solution.shortestToChar("abcdefghijklmnopqrstuvwxyz",'m');System.out.println("Test 9: "+Arrays.toString(result9));// [12,11,10,9,8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8,9,10,11,12,13]// 测试用例10:目标字符在中间int[]result10=solution.shortestToChar("abcde",'c');System.out.println("Test 10: "+Arrays.toString(result10));// [2,1,0,1,2]}两次遍历:
初始化:
Integer.MAX_VALUE防止溢出距离计算:
i - prev(prev ≤ i)prev - i(prev ≥ i)边界处理: