• 华为OD机考算法题:字符串比较


    目录

    题目部分

    解读与分析

    代码实现


    题目部分

    题目字符串比较
    难度
    题目说明给定字符串A、B和正整数V,A的长度与B的长度相等,请计算A中满足如下条件的最大连续子串的长度:
    1、该连续子串在A和B中的位置和长度均相同。
    2、该连续子串|A[i]–B[i]|之和小于等于V。其中|A[i]–B[i]|表示两个字母ASCII码之差的绝对值。
    输入描述输入为三行:
    第一行为字符串A,仅包含小写字符,1<=A.length<=1000。
    第二行为字符串B,仅包含小写字符,1<=B.length<=1000。
    第三行为正整数V,0<=V<=10000。
    输出描述字符串最大连续子串的长度,要求该子串|A[i]–B[i]|之和小于等于V。
    补充说明
    ------------------------------------------------------
    示例
    示例1
    输入xxcdefg
    cdefghi
    5
    输出2
    说明字符串 A 为 xxcdefg,字符串 B 为 cdefghi,V = 5。
    它的最大连续子串可以是 cd -> ef、de -> fg、ef -> gh、fg -> hi,所以最大连续子串是 2。


    解读与分析

    题目解读

    两个字符串A、B的长度相等,设下标为 i 的字符 A[i] 与 B[i] 对应的 ASCII 码的绝对值为 diffAbs[i]。diffAbs 中连续的 n 个元素之和小于或等于 V,求 n 的最大值。

    分析与思路

    此题虽然难度虽然是“难”,实际很简单。

    先遍历字符串A、B,依次计算每一个字符 A[i]、B[i] 的 ASCII 码的绝对值之差,存放到整型数组 diffAbs 中。

    接着遍历 diffAbs,从第一个元素 diffAbs[0] 开始寻找连续元素之和小于或等于 V 的区块,设区块的左下标为 leftIndex,右下标为 rightIndex。初始值 leftIndex、rightIndex 均为 0,当区块中元素之和大于 V 时,leftIndex 向右移动(注意要保证 rightIndex >= leftIndex);当和小于 rightIndex 时,rightIndex 往右移动。直到 rightIndex 到达最后一个元素。在滑动过程中,( rightIndex - leftIndex + 1 ) 的最大值即为最大的连续个数。

    需要遍历两次,其中第一次为遍历字符串A、B,第二次遍历数组 diffAbs。时间复杂度和空间复杂度均为 O(n)。

    此题和往期的题《华为OD机考算法题:补种未成活胡杨》《华为OD机考算法题:根据某条件聚类最少交换次数》《华为OD机考算法题:区块链文件转储系统》比较类似。


    代码实现

    Java代码

    1. import java.util.Scanner;
    2. /**
    3. * 字符串比较
    4. * @since 2023.10.09
    5. * @version 0.1
    6. * @author Frank
    7. *
    8. */
    9. public class StringComparation {
    10. public static void main(String[] args) {
    11. Scanner sc = new Scanner(System.in);
    12. while (sc.hasNext()) {
    13. String strA = sc.nextLine();
    14. String strB = sc.nextLine();
    15. String strV = sc.nextLine();
    16. int v = Integer.parseInt( strV );
    17. processStringComparation( strA, strB, v );
    18. }
    19. }
    20. private static void processStringComparation( String strA, String strB, int v )
    21. {
    22. int[] diffAbs = new int[ strA.length() ];
    23. for( int i = 0; i < diffAbs.length; i ++ )
    24. {
    25. int eachDiffAbs = Math.abs( strA.charAt( i ) - strB.charAt( i ) );
    26. diffAbs[i] = eachDiffAbs;
    27. }
    28. int leftIndex = 0;
    29. int rightIndex = 0;
    30. int maxCount = 0;
    31. int curSum = diffAbs[0];
    32. while( rightIndex <= diffAbs.length - 1 )
    33. {
    34. if( curSum > v )
    35. {
    36. if( leftIndex >= diffAbs.length - 1 )
    37. {
    38. break;
    39. }
    40. curSum -= diffAbs[ leftIndex ];
    41. leftIndex ++;
    42. if( rightIndex < leftIndex )
    43. {
    44. rightIndex = leftIndex;
    45. curSum += diffAbs[ rightIndex ];
    46. }
    47. continue;
    48. }
    49. // curSum <= v
    50. if( rightIndex - leftIndex + 1 >= maxCount )
    51. {
    52. maxCount = rightIndex - leftIndex + 1;
    53. }
    54. if( rightIndex >= diffAbs.length - 1 )
    55. {
    56. break;
    57. }
    58. rightIndex ++;
    59. curSum += diffAbs[ rightIndex ];
    60. }
    61. System.out.println( maxCount );
    62. }
    63. }

    JavaScript代码

    1. const rl = require("readline").createInterface({ input: process.stdin });
    2. var iter = rl[Symbol.asyncIterator]();
    3. const readline = async () => (await iter.next()).value;
    4. void async function() {
    5. while (line = await readline()) {
    6. var strA = line;
    7. var strB = await readline();
    8. var strV = await readline();
    9. var v = parseInt(strV);
    10. processStringComparation(strA, strB, v);
    11. }
    12. }();
    13. function processStringComparation(strA, strB, v) {
    14. var diffAbs = new Array();
    15. for (var i = 0; i < strA.length; i++) {
    16. var eachDiffAbs = Math.abs(strA.charCodeAt(i) - strB.charCodeAt(i));
    17. diffAbs[i] = eachDiffAbs;
    18. }
    19. var leftIndex = 0;
    20. var rightIndex = 0;
    21. var maxCount = 0;
    22. var curSum = diffAbs[0];
    23. while (rightIndex <= diffAbs.length - 1) {
    24. if (curSum > v) {
    25. if (leftIndex >= diffAbs.length - 1) {
    26. break;
    27. }
    28. curSum -= diffAbs[leftIndex];
    29. leftIndex++;
    30. if (rightIndex < leftIndex) {
    31. rightIndex = leftIndex;
    32. curSum += diffAbs[rightIndex];
    33. }
    34. continue;
    35. }
    36. // curSum <= v
    37. if (rightIndex - leftIndex + 1 >= maxCount) {
    38. maxCount = rightIndex - leftIndex + 1;
    39. }
    40. if (rightIndex >= diffAbs.length - 1) {
    41. break;
    42. }
    43. rightIndex++;
    44. curSum += diffAbs[rightIndex];
    45. }
    46. console.log(maxCount);
    47. }

    (完)

  • 相关阅读:
    Postman接口测试工具
    文章系列2:Unraveling the functional dark matter through global metagenomics
    如何使用Etherscan Remix插件验证智能合约
    分别用c++,python,java写一个解决约瑟夫环问题的代码
    关于plt.scatter()的使用
    web课程设计 基于html+css+javascript+jquery女性化妆品商城
    《人类简史》笔记二——一场永远的革命
    Spark简介
    Python从入门到入土-进阶语法
    机器学习——K最近邻算法(KNN)
  • 原文地址:https://blog.csdn.net/ZiJinShi/article/details/133677033