• 华为OD机考算法题:计算最大乘积


    题目部分

    题目计算最大乘积
    难度
    题目说明给定一个元素类型为小写字符串的数组,请计算两个没有相同字符的元素长度乘积的最大值。
    如果没有符合条件的两个元素,返回 0。
    输入描述输入为一个半角逗号分隔的小写字符串的数组,2<= 数组长度<=100,0< 字符串长度<= 50。
    输出描述两个没有相同字符的元素长度乘积的最大值。
    补充说明
    ------------------------------------------------------
    示例
    示例1
    输入iwdvpbn,hk,iuop,iikd,kadgpf
    输出14
    说明数组中有 5 个元素。
    iwdvpbn 与 hk 无相同的字符,满足条件,iwdvpbn 长度为 7,hk 长度为 2,乘积为 14 (7 * 2)。
    iwdvpbn 与 iuop、iikd、kadgpf 都有相同的字符,不满足条件。
    iuop 与 iikd、kadgpf 均有相同的字符,不满足条件。
    iikd 与 kadgpf 有相同的字符,不满足条件。
    因此,输出为 14。


    解读与分析

    题目解读

    给定一个长字符串,以 “,” 为间隔符分隔成多个字符串。请从这些字符串中找出两个字符串,保证在这两个字符串中不存在相同字符的前提下,使两个字符串的长度的乘积最大。

    分析与思路

    此题的步骤可以分为解析字符串,排序、数据初始化、遍历,详细说明如下:
    1. 解析字符串。对输入的字符串以 “,” 为间隔符,把它们解析成多个字符串,放到数组 stringArr 中。
    2. 对数组 stringArr 排序。排序规则为长度最长的字符串排在最前面。
    3. 数据初始化。对已排序的 stringArr,统计每个元素(字符串)所包含的字符,放到集合中;计算字符串的长度。创建两个数组,第一个数组为 charSetArr,其第 i 个元素为 stringArr 中第 i 个元素包含的字符结合;第二个数组 lengArr,其第 i 个元素为 stringArr 中第 i 个元素的长度。
    4. 遍历。
    1)  初始化乘积,设为 maxProduct,初始值 0。
    2)  两两比较字符串。把字符串 stringArr[0] 分别与 
    stringArr[1]、stringArr[2] …… stringArr[n -1] 进行比较;之后把字符串 stringArr[1] 分别与 stringArr[2]、stringArr[3] …… stringArr[n -1] 比较。
    比较规则是,在比较时,如果不存在交集,即charSetArr[0] 与 charSetArr[i] 不存在交集,则计算 lengthArr[0] 与 lengthArr[i] 的乘积,设为 tmpProduct,如果 tmpProduct 大于 maxProduct,则把 tmpProduct 赋值个 maxProduct。当找到 charSetArr[0] 与 charSetArr[i] 不存在交集后,不再判断 charSetArr[0]
    与  其他字符串是否存在交集,因为已经不存在乘积比它更大。

    此方法的时间复杂度为 O(n^{2}),空间复杂度为O(n^{2})。


    代码实现

    Java代码

    1. import java.util.Arrays;
    2. import java.util.Collections;
    3. import java.util.Comparator;
    4. import java.util.HashSet;
    5. import java.util.Scanner;
    6. import java.util.Set;
    7. /**
    8. * 计算最大乘积
    9. *
    10. * @version 0.1
    11. * @author Frank
    12. *
    13. */
    14. public class StringLengthMaxProduct {
    15. public static void main(String[] args) {
    16. Scanner sc = new Scanner(System.in);
    17. while (sc.hasNext()) {
    18. String input = sc.nextLine();
    19. processStringLengthMaxProduct( input );
    20. }
    21. }
    22. private static void processStringLengthMaxProduct( String input )
    23. {
    24. String[] strArr = input.split( "," );
    25. Arrays.sort( strArr, new Comparator<String>() {
    26. @Override
    27. public int compare(String o1, String o2) {
    28. // 长度最长的排在最前面
    29. return o2.length() - o1.length();
    30. }
    31. });
    32. Set[] charSetArr = new HashSet[ strArr.length ];
    33. int[] lengthArr = new int[ strArr.length ];
    34. initCharSetInfo( strArr, charSetArr, lengthArr );
    35. int ret = getMaxProduct( charSetArr, lengthArr );
    36. System.out.println( ret );
    37. }
    38. private static void initCharSetInfo( String[] strArr, Set[] charSetArr,int[] lengthArr )
    39. {
    40. for( int i = 0; i < strArr.length; i ++ )
    41. {
    42. String curStr = strArr[i];
    43. lengthArr[i] = curStr.length();
    44. Set<Character> curSet = new HashSet<Character>();
    45. for( int j = 0; j < curStr.length(); j ++ )
    46. {
    47. curSet.add( curStr.charAt( j ) );
    48. }
    49. charSetArr[i] = curSet;
    50. }
    51. }
    52. private static int getMaxProduct( Set[] charSetArr,int[] lengthArr )
    53. {
    54. int maxProduct = 0;
    55. int size = charSetArr.length;
    56. boolean needBreak = false;
    57. for( int i = 0; i < size; i ++ )
    58. {
    59. for( int j = i + 1; j < size; j ++ )
    60. {
    61. if( ( j == i + 1 ) && ( lengthArr[i] * lengthArr[j] < maxProduct ) )
    62. {
    63. needBreak = true;
    64. break;
    65. }
    66. // 包含相同字符
    67. if( !Collections.disjoint( charSetArr[i], charSetArr[j]))
    68. {
    69. continue;
    70. }
    71. int product = lengthArr[i] * lengthArr[j];
    72. if( product > maxProduct)
    73. {
    74. maxProduct = product;
    75. }
    76. break;
    77. }
    78. if( needBreak )
    79. {
    80. break;
    81. }
    82. }
    83. return maxProduct;
    84. }
    85. }

    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. processStringLengthMaxProduct(line);
    7. }
    8. }();
    9. function processStringLengthMaxProduct(input) {
    10. var strArr = input.split(",");
    11. strArr.sort(function(a, b) {
    12. return b.length - a.length;
    13. });
    14. var charSetArr = new Array();
    15. var lengthArr = new Array();
    16. initCharSetInfo(strArr, charSetArr, lengthArr);
    17. var ret = getMaxProduct(charSetArr, lengthArr);
    18. console.log(ret);
    19. }
    20. function initCharSetInfo(strArr, charSetArr, lengthArr) {
    21. for (var i = 0; i < strArr.length; i++) {
    22. var curStr = strArr[i];
    23. lengthArr[i] = curStr.length;
    24. var curSet = new Set();
    25. for (var j = 0; j < curStr.length; j++) {
    26. curSet.add(curStr.charAt(j));
    27. }
    28. charSetArr[i] = curSet;
    29. }
    30. }
    31. function getMaxProduct(charSetArr, lengthArr) {
    32. var maxProduct = 0;
    33. var size = charSetArr.length;
    34. var needBreak = false;
    35. for (var i = 0; i < size; i++) {
    36. for (var j = i + 1; j < size; j++) {
    37. if ((j == i + 1) && (lengthArr[i] * lengthArr[j] < maxProduct)) {
    38. needBreak = true;
    39. break;
    40. }
    41. // 包含相同字符
    42. if (!isSetDisjoint(charSetArr[i], charSetArr[j])) {
    43. continue;
    44. }
    45. var product = lengthArr[i] * lengthArr[j];
    46. if (product > maxProduct) {
    47. maxProduct = product;
    48. }
    49. break;
    50. }
    51. if (needBreak) {
    52. break;
    53. }
    54. }
    55. return maxProduct;
    56. }
    57. function isSetDisjoint(charSet1, charSet2) {
    58. for (var ele of charSet2) {
    59. if (charSet1.has(ele)) {
    60. return false;
    61. }
    62. }
    63. return true;
    64. }

    (完)

  • 相关阅读:
    单调栈题目:找出最具竞争力的子序列
    linux性能监控sar
    Flutter 实战:构建跨平台应用
    ib中文诗歌赏析,诗歌主题怎么入手?
    删除表数据
    python打印带下标的字母组合
    允许访问:掌握权限的艺术
    MySQL运维2-主从复制
    微信小程序:EventChannel实现页面间事件通信通道
    新能源车补能;小鹏、蔚来各有千秋
  • 原文地址:https://blog.csdn.net/ZiJinShi/article/details/134073708