当前位置: 首页 > 面试题库 >

陷入Java面试中,需要一些提示

嵇光临
2023-03-14
问题内容

这是我坚持的面试问题:

给定一个由a,b和c组成的字符串,我们可以执行以下操作:取任意两个相邻的不同字符并将其替换为第三个字符。例如,如果“ a”和“
c”相邻,则可以将其替换为“ b”。重复应用此操作可能导致的最小字符串是多少?

我尝试的解决方案:

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;

public class Solution {
    public static void main(String[] args) {
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    System.in));

            System.out.println(solve(in.readLine()));

            in.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static int solve(String testCase) {
        LinkedList<String> temp = new LinkedList<String>(deconstruct(testCase));

        for (int i = 0; i < (temp.size() - 1); i++) {
            if (!temp.get(i).equals(temp.get(i + 1))) {
                temp.add(i, getThirdChar(temp.remove(), temp.remove()));
                i = -1;
            }
        }

        return reconstruct(temp).length();
    }

    private static List<String> deconstruct(String testCase) {
        List<String> temp = new LinkedList<String>();

        for (int i = 0; i < testCase.length(); i++) {
            temp.add(testCase.charAt(i) + "");
        }

        return temp;
    }

    private static String reconstruct(List<String> temp) {
        String testCase = "";

        for (int i = 0; i < temp.size(); i++) {
            testCase += temp.get(i);
        }

        return testCase;
    }

    private static String getThirdChar(String firstChar, String secondChar) {
        return "abc".replaceAll("[" + firstChar + secondChar + "]+", "");
    }
}

该代码似乎可以在测试输入“ cab”(打印“ 2”),“ bcab”(打印“ 1”)和“ ccccc”(打印“
5”)上正常工作。但是我一直被告知我的代码是错误的。谁能帮助我找出错误所在?


问题答案:

正如人们已经指出的那样,错误是您的算法以预定义的顺序进行替换。您的算法将进行转换:

abcc --> ccc 代替 abcc --> aac --> ab --> c

如果要使用生成精简字符串的技术,则需要:

  • 以所有可以想象的顺序(而不是仅一个预定义的迭代顺序)在一个级别上执行替换
  • 找到一种明智的方法来确定哪种替换将最终产生最短的字符串

如果您只需要缩略字符串的长度,那么可以使用一种更简单的实现,它不需要生成缩略字符串。这是@Matteo答案的扩展版本,具有更多详细信息和有效的(非常简单的)算法。

简单属性

我假设在给定的规则集下,关于abc字符串,以下三个属性是正确的。

  1. 如果无法进一步缩小字符串,则该字符串中的所有字符必须为同一字符。

  2. 不可能:2 < answer < string.length是真的

  3. 执行归约运算时,如果运算前每个字母的计数为偶数,则运算后每个字母的计数将为奇数。相反,如果在操作之前每个字母的计数为奇数,则在操作之后的计数将为偶数。

物业1

属性一是微不足道的。

属性2(示例说明)

假设:我们有一个长度为5的精简串,以后再也不能精简。

AAAAA

由于此字符串是归约运算的结果,因此前一个字符串必须包含one B和one C。以下是可能的“父字符串”的一些示例

BCAAAAAABCAAAAACBA

对于所有可能的父字符串,我们可以很容易地看到C:s和B:s中的至少一个可以与A:s而不是彼此组合。这将导致长度为5的字符串,该字符串将进一步减少。因此,我们已经说明了我们拥有不可约的长度为5的字符串的唯一原因是,我们在执行归约运算时没有正确选择要合并的字符。

这种推理适用于所有长度为k的简化字符串2 < k < string.length

属性3(示例说明)

例如[numA, numB, numC] = [even, even, even],如果有一个折减运算,我们用AB用AB代替AB。A和B的计数将减少1,使计数为奇数,而C的计数将增加1,使计数为奇数。好。

与此类似,如果两个计数为偶数且一个为奇数,则两个计数将为奇数,而在操作后甚至为一个,反之亦然。

换句话说,如果所有三个计数都具有相同的“均匀度”,那么任何减法运算都不能改变它。并且,如果计数的“均匀性”存在差异,则任何减法运算都无法更改该数值。

从属性得出结论

考虑两个不可约的字符串:

AAA

对于A通知,[numA, numB, numC] = [odd, even, even] 对于AA通知,[numA, numB, numC] = [even, even, even]

现在忘记这两个字符串,并假设我们得到了长度为n的输入字符串。

如果字符串中的所有字符都相等,则答案显然是string.length。

另外,我们从属性2知道可以将字符串缩小到小于3的长度。我们还知道对执行缩小操作的均匀性的影响。如果输入的字符串包含所有字母或所有字母的奇计甚至数,也不可能将其降低到一个字母串,因为它是不可能均匀性结构改变,从[even, even, even][odd, even, even]通过执行还原操作。

因此,一个更简单的算法如下:

算法

Count the number of occurences of each letter in the input string [numA, numB, numC]

If two of these counts are 0, then return string.length

Else if (all counts are even) or (all counts are odd), then return 2

Else, then return 1


 类似资料:
  • 问题内容: 为了避免锁定,在对表进行进一步操作之前需要提交的语句列表有哪些?我不是在谈论具有多个语句和交易完整性的完整交易;相反,我指的是单个语句。 我知道插入应该被提交,但是截断具有自动提交。需要提交的完整语句清单是什么? 需要提交(入门列表): 问题答案: 需要提交/回退DML(数据操作语言)命令。这是这些命令的列表。 数据操作语言(DML)语句用于管理架构对象中的数据。一些例子:

  • 本文向大家介绍缺陷报告包括哪些要素?相关面试题,主要包含被问及缺陷报告包括哪些要素?时的应答技巧和注意事项,需要的朋友参考一下 1)和bug产生对应的软件版本 2)开发的接口人员 3)bug的优先级 4)bug的严重程度 5)bug可能属于的模块,如果不能确认,可以用开发人员来判断 6)bug标题,需要清晰的描述现象 7)bug描述,需要尽量给出重新bug的步骤 8)bug附件中能给出相关的日志和

  • 我想知道这里的日常工作是如何进行的。 获取以下错误: *****我是主要的围棋套路***** 等待消息的主例程 goroutine 5[chan receive]: main.main.func1(0xC420054060) /users/work/go/src/github.com/golang_play/goroutine/goroutine.go:13+0x98由main.main/user

  • 我这里有3个实体A、B和C。 实体A和实体B都与实体C有关系。在我的例子中,我有一个来自实体A的当前id,并且我想使用来自实体C的查询到达实体B。 多谢了。

  • 问题内容: 我有一段我想缩短的代码… 我一次又一次地添加新的标志权限感到非常恼火,我需要做几次,是否有一个较短的方法可以将所有标志放在同一个定义中? 让我这样说吧,我可以这样做吗?(当然这会产生错误,但是类似。) 问题答案: 如果与C#的语法相同,并且标志设置正确,则可以执行以下操作:

  • 本文向大家介绍学Java做项目需要学习的一些技能,包括了学Java做项目需要学习的一些技能的使用技巧和注意事项,需要的朋友参考一下 Java就是用来做项目的!Java的主要应用领域就是企业级的项目开发!要想从事企业级的项目开发,你必须掌握如下要点: 1、掌握项目开发的基本步骤 2、具备极强的面向对象的分析与设计技巧 3、掌握用例驱动、以架构为核心的主流开发方法 没有人愿意自己一辈子就满足于掌握了一