java经典问题:连个字符串互为回环变位

 更新时间:2017年11月14日 14:19:17   作者:Kkky  
连个字符串互为回环变位经常出现在java程序员面试中,这个是考验程序员的解题思路和方法的最经典的一题,小编为大家详细分析一下,一起来学习吧。

本次给大家带来的是关于判断连个字符串是否互为回环变位(Circular Rotaion)的java程序员面试经常出现的题型,给大家做了两种方式的解答,希望能帮助到你。

一般情况下都是笔试或者是直接上机操作,题型一般都是:如果字符串 s 中的字符循环移动任意位置之后能够得到另一个字符串 t,那么 s 就被称为 t 的回环变位(circular rotation)。

A string s is a circular rotation of a string t if it matches when the characters are circularly shifted by any number of positions;
e.g., ACTGACG is a circular shift of TGACGAC, and vice versa. Detecting this condition is important in the study of genomic sequences.
Write a program that checks whether two given strings s and t are circular.

关于解答方面,我给在这里给出了2种方式:
解法一:
将s拆分成左右两部分,然后另令s'=右+左,遍历所有情况。如果是回环字符串的话,其中会有 s'=t 的情况。

public static boolean isCircularRotation(String s, String t) {
    if (s.length() != t.length())
      return false;
    int sLen = s.length();
    for (int i = 0; i <= sLen; i++) {
      // 注意subString的后角标的界限
      String sLeft = s.substring(0, i);
      String sRigth = s.substring(i + 1, sLen);
      if ((sRigth + sLeft).equals(t))
        return true;
    }
    return false;
  }

解法二:(巧妙)

public static boolean isCircularRotation_1(String s, String t) {
  return (s.length() == t.length() && (t + t).contains(s));
}

以上就是基本快速的两种解决方式,关于这个问题,再给大家看一篇很详细的判断字符串回环变位解决思路:

如果字符串s中的字符循环移动任意位置之后能够得到另一字符串t,那么s就被称为t的回环变位。例如,ACTGACG 就是 TGACGAC 的一个回环变位,反之亦然。判定这个条件在基因组序列中的研究是十分重要的。编写一个算法检查两个给定的字符串s和t是否互为回环变位。

这是我在《算法(第四版)》里看到的一道练习题 ,当时的第一想法就是遍历字符串 t,从不同的索引位置将字符串t分解成两个子串,交换顺序拼接后再与s相比是否相等。算法如下:

 public static boolean isCircularRotation(String s, String t) {
    if (s.length() != t.length()) {
      return false;
    }
    int length = s.length();
    for (int i = 1; i <= length; i++) {
      String left = s.substring(0, i);
      String right = s.substring(i, length);
      if ((right + left).equals(t)) {
        return true;
      }
    }
    return false;
  }

后来看答案,提示说可以用一行代码就能搞定了。当时想了想,感觉不太可能,就作罢了。今天重新开始学习这本书的时候,再次看到这道题,突然有了想法代码如下:

public static boolean isCircularRotation(String s, String t) {
    return s.length() == t.length() && (t + t).contains(s);
  }

解释:如果字符串s和t互为回环变位,则s可分解为“AB”,t可分解为“BA”。那么t与自身拼接后则为“BABA”,显然是会包含s的。这种思路比较巧妙,当然了,自认为算法效率并没有什么提高。

为什么大家都会对这个经典的JAVA问题困惑着?最主要的原因就是解题的思路问题:

容易想复杂的"回环变位",思路错误,问题就会复杂化,一起来看下经典的误区和最终想明白以后的解法。

题目描述很简单:
如果字符串s重的字符循环移动任意位置之后能够得到另一个字符串t,那么s就被成为s的回环变位(circular rotation) 举例省略…
问题:请编写一个程序检查2个给定的字符串s和t是否互为回环变位。
提示:判断条件只需要一行代码

看到题目当时满脑子想的都是双重循环啊,游标移动啊各种i,j,k……
结果来一句这样的提示,当时我就受不了了,决定去看一下答案….

答案是这样的

(s.length() == t.length()) && (s.concat(s).indexOf(t) >= 0)

乍一看,好像真的可以…顿时鄙视了自己的各种游标循环i,j,k…
(虽然可能底层也是各种循环游标i,j,k,但是别人都实现了的基类直接用明显更省事…)

但是也发现自己对String类的concat函数和indexOf的各种重载不懂

一下是jdk文档的描述

public String concat(String str)将指定字符串连接到此字符串的结尾。 
如果参数字符串的长度为 0,则返回此 String 对象。否则,创建一个新的 String 对象,用来表示由此 String 对象表示的字符序列和参数字符串表示的字符序列连接而成的字符序列。

示例: 

 "cares".concat("s") returns "caress"
 "to".concat("get").concat("her") returns "together"

参数:
str - 连接到此 String 结尾的 String。 
返回:
一个字符串,它表示在此对象字符后连接字符串参数字符而成的字符。
public int indexOf(String str)返回指定子字符串在此字符串中第一次出现处的索引。返回的整数是 
 this.startsWith(str, k)
 为 true 的最小 k 值。 

参数:
str - 任意字符串。 
返回:
如果字符串参数作为一个子字符串在此对象中出现,则返回第一个这种子字符串的第一个字符的索引;如果它不作为一个子字符串出现,则返回 -1。

关于这个问题,已经在上文章阐述的非常清楚了,大家如果对此还有任何的疑问,可以在本文下方留言讨论。

相关文章

  • Java中如何正确重写equals方法

    Java中如何正确重写equals方法

    Object类中equals方法比较的是两个对象的引用地址,只有对象的引用地址指向同一个地址时,才认为这两个地址是相等的,否则这两个对象就不相等
    2021-10-10
  • 基于swing实现窗体拖拽和拉伸

    基于swing实现窗体拖拽和拉伸

    这篇文章主要为大家详细介绍了基于swing实现窗体拖拽和拉伸,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • Java调用高德地图API根据详细地址获取经纬度详细教程

    Java调用高德地图API根据详细地址获取经纬度详细教程

    写了一个经纬度相关的工具,分享给有需求的小伙伴们,下面这篇文章主要给大家介绍了关于Java调用高德地图API根据详细地址获取经纬度,文中通过图文以及代码介绍的非常详细,需要的朋友可以参考下
    2024-04-04
  • Springcloud微服务架构基础知识解析

    Springcloud微服务架构基础知识解析

    这篇文章主要介绍了Springcloud微服务架构基础知识解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • MyBatisPlus超详细分析条件查询

    MyBatisPlus超详细分析条件查询

    这篇文章主要介绍了MyBatisPlus条件查询的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • Java中的Unsafe在安全领域的使用总结和复现(实例详解)

    Java中的Unsafe在安全领域的使用总结和复现(实例详解)

    unsafe里面有很多好用的方法,比如allocateInstance可以直接创建实例对象,defineAnonymousClass可以创建一个VM匿名类(VM Anonymous Class),以及直接从内存级别修改对象的值。这篇文章主要介绍了Java中的Unsafe在安全领域的一些应用总结和复现,需要的朋友可以参考下
    2022-03-03
  • 基于Java生成GUID的实现方法

    基于Java生成GUID的实现方法

    本篇文章是对Java生成GUID的方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 解析springboot集成AOP实现日志输出的方法

    解析springboot集成AOP实现日志输出的方法

    如果这需要在每一个controller层去写的话代码过于重复,于是就使用AOP定义切面 对其接口调用前后进行拦截日志输出。接下来通过本文给大家介绍springboot集成AOP实现日志输出,需要的朋友可以参考下
    2021-11-11
  • Java RandomAccessFile 指定位置实现文件读取与写入

    Java RandomAccessFile 指定位置实现文件读取与写入

    这篇文章主要介绍了Java RandomAccessFile 指定位置实现文件读取与写入的相关资料,需要的朋友可以参考下
    2017-01-01
  • 将Springboot项目升级成Springcloud项目的图文教程

    将Springboot项目升级成Springcloud项目的图文教程

    本文主要介绍了将Springboot项目升级成Springcloud项目,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06

最新评论