翻转单词顺序

  • 题目:输入一个英文句子,翻转句子中的单词顺序,但是单词内的字符顺序不变,例如:I am a software engineer -> engineer software a am I
方案一:空间换时间
  • 空间换时间方法,还是如上案例中,I am a software engineer,分析如上:

    • 统计出字符串中空格位置,按空格拆分
    • 通过空格的顺序逐个拆解原字符串
    • 将拆解后的字符串按照单词从后面开始复制
    • 例如最后一个空格位置 15,那么第一个单词的位置应该是15+1 ~ str.length-1
    • 依次类推逐个向前复制
    • 如下图所示
  • 如上分析有如下代码:
/*** 反转字符串中单词顺序,I am a software engineer -> engineer software a am I* @author liaojiamin* @Date:Created in 16:59 2021/7/1*/
public class ReverStr {public static void main(String[] args) {String str = "I am a software engineer";char[] target = str.toCharArray();char[] result = reverMyStr(target);for (char c : result) {System.out.print(c);}}/*** 方案一:空间换时间方法,* 空间复杂度O(n),时间复杂度O(n)* */public static char[] reverMyStr(char[] target){if(target == null || target.length <= 0){return target;}int[] isSpace = new int[target.length];int positionSpace = 0;char[] result = new char[target.length];int resultPosition = 0;for (int i = 0; i < target.length; i++) {if(target[i] == ' '){isSpace[positionSpace++] = i;}}int positionEnd = target.length -1;positionSpace--;for (int i = positionSpace; ; i--) {int start = 0;if(i>=0){start = isSpace[i] + 1;}result = splitCharArray(start, positionEnd, target, result, resultPosition);resultPosition += (positionEnd - start +1);if(start != 0){//最后一次不需要再添加空格result[resultPosition++]=' ';positionEnd = isSpace[i] -1;}if(start == 0){return result;}}}public static char[] splitCharArray(int start, int end, char[] target, char[] result, int position){for(int i=start; i <=end;i++){result[position++] = target[i];}return result;}
}
  • 方案一中其实就是模拟一个字符串拆分函数split,只是在拆分后在对具体的单词进行顺序的变化,整体时间复杂度,第一次遍历得出拆分点空格,第二次逐个对拆分后的字符进行复制,所以时间复杂度O(n),空间复杂度O(n)
方案二:多次翻转
  • 本题中需要得到单个单词顺序上的翻转,但是实际字符是正向的,分析如下:

    • 翻转字符串,得到一个完全翻转的,此时目的在于,然后面的单词位置能移动到签名,实现单词顺序的变化
    • 此时得到的是一个单词,字母都是逆序的字符串
    • 统计现有字符串中空格,依据空格区分每个单词
    • 分别对每个单词字符串进行单独翻转得到最终结果。
    • 如下图:

  • 经如上分析有如下代码:
/*** 反转字符串中单词顺序,I am a software engineer -> engineer software a am I* @author liaojiamin* @Date:Created in 16:59 2021/7/1*/
public class ReverStr {public static void main(String[] args) {String str = "I am a software engineer";char[] target = str.toCharArray();char[] result_1 = reverTwice(target);for (char c : result_1) {System.out.print(c);}}/*** 方案二:反转两次* 先全部反转字符,在逐个单词颠倒* 时间复杂度O(n) 空间复杂度O(1)* */public static char[] reverTwice(char[] target){if(target == null || target.length <= 0){return target;}target = reverAll(target, 0, target.length -1);int[] isSpace = new int[target.length];int positionSpace = 0;for (int i = 0; i < target.length; i++) {if(target[i] == ' '){isSpace[positionSpace++] = i;}}positionSpace--;int start = 0;for (int i = 0; ; i++) {int end = target.length -1;if(i <= positionSpace){end = isSpace[i] - 1;}target = reverAll(target, start, end);if(i <= positionSpace){start = isSpace[i] +1;}else {return target;}}}/*** 按指定位置反转* */public static char[] reverAll(char[] target, int start, int end){while (start < end){char temp = target[start];target[start] = target[end];target[end] = temp;start++;end--;}return target;}
}

变种题型

  • 题目:定义字符串的左旋转操作就是把字符串签名的若干字符转移到字符的尾部。请定义一个函数,实现字符串的左旋操作功能, 例如输入字符串I am a software engineer 4 -> a software engineerI am
方案一:空间换时间
  • 最直观的方法,直接定义一个新的数组复制需要的段。分析如下:

    • 如上题案例中,只需要将指定前面的字符转到最后,如果用字符串移动每个字符都要操作 指定数子的次数
    • 如果定义新的数组,则只需要将指定阶段复制过去
    • 如上指定位4,我们先将后面字符串 5~length-1 位置的字符复制到新数组开始位置
    • 然后将0~4 位置数组复制到新数组的后面
    • 得到的新数组就是我们需要的结果
    • 如下图

  • 如上分析有如下代码
/*** 指定位置反转字符串* 案例 I am a software engineer 4 -> a software engineerI am* @author liaojiamin* @Date:Created in 18:47 2021/7/1*/
public class ReverPositionStr {public static void main(String[] args) {char[] target = "I am a software engineer".toCharArray();char[] result = reverPosition(target, 4);for (char c : result) {System.out.print(c);}}/*** 方案一:空间换时间* 时间复杂度O(n),空间复杂度O(n)* */public static char[] reverPosition(char[] target, int position){if(target == null || target.length <= 0 || target.length <= position){return target;}char[] result = new char[target.length];int positionResult = 0;for (int i = position; i < target.length; i++) {result[positionResult++]=target[i];}for(int i=0;i<position;i++){result[positionResult++] = target[i];}return result;}
}
  • 如上案例实现,遍历一次数组即可完成复制,因此时间复杂度O(n),空间复杂度显然是O(n)
方案二:多次翻转
  • 依据第一题中的思路,有如下分析:

    • 既然需要翻转指定位置,我们可以将本字符串看成是两个单词,
    • 本次单词通过指定的位置进行拆分,这样理解的话就和第一题是一模一样的
    • 我们依然多次翻转,第一次全文翻转,得到一个顺序上是正确的字符
    • 第二次,依据指定位置4,此时的位置应该是 length-1-4+1 ~length-1的位置翻转
    • 第三次,翻转0~length-1-4 的位置,得到我们需要的值

  • 如上分析有如下代码:
/*** 指定位置反转字符串* 案例 I am a software engineer 4 -> a software engineerI am* @author liaojiamin* @Date:Created in 18:47 2021/7/1*/
public class ReverPositionStr {public static void main(String[] args) {char[] target = "I am a software engineer".toCharArray();char[] result_1 = reverPositionTwice(target, 4);for (char c : result_1) {System.out.print(c);}}/*** 方案二:反转两次* 时间复杂度O(n)** */public static char[] reverPositionTwice(char[] target, int position){if(target == null || target.length <= 0 || target.length <= position){return target;}target = reverAll(target, 0, target.length -1);target = reverAll(target, 0, target.length-1 - position);target = reverAll(target, target.length-1 - position + 1, target.length-1);return target;}/*** 按指定位置反转* */public static char[] reverAll(char[] target, int start, int end){while (start < end){char temp = target[start];target[start] = target[end];target[end] = temp;start++;end--;}return target;}
}

上一篇:数据结构与算法–有序数组中找出和为s的两个数字
下一篇:数据结构与算法–判断扑克牌是否顺子

数据结构与算法--翻转单词顺序相关推荐

  1. 翻转单词文本 c语言,编程算法 - 翻转单词顺序 代码(C)

    翻转单词顺序 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入一个英文句子, 翻转句子中单词的顺序, 但单词内字符的顺序不变. 首先翻转(r ...

  2. 【LeetCode】剑指 Offer 58 - I. 翻转单词顺序

    [LeetCode]剑指 Offer 58 - I. 翻转单词顺序 文章目录 [LeetCode]剑指 Offer 58 - I. 翻转单词顺序 一.双指针 一.双指针 算法解析: 倒序遍历字符串 s ...

  3. 剑指offer——面试题42-2:翻转单词顺序

    剑指offer--面试题42-2:翻转单词顺序 20180906整理 Solution1: 自己想的垃圾算法 对于c++中的string对象,substr()和erase()函数都是很常用的,常见用法 ...

  4. 【剑指offer-Java版】42翻转单词顺序VS左旋转字符串

    反转单词顺序以及左旋转字符串:输入一个英文句子,翻转句子中的单词顺序,单词内部的字母顺序是不变的 – I am a student. -> student. am I 第一步,翻转句子中的所有字 ...

  5. LeetCode-剑指 Offer 58 - I. 翻转单词顺序

    剑指 Offer 58 - I. 翻转单词顺序 思路一:也是核心思想,就是先把句子中所有字符串取出放入字符串数组,再对数组中的字符串进行操作后重新连接即可,具体问题具体细节还需要按题目要求分析 而遍历 ...

  6. [剑指offer]面试题42:翻转单词顺序 VS左旋转字符串

    面试题42:翻转单词顺序 VS左旋转字符串 题目一:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变.为简单起见,标点符号和普通字母一样处理.例如输入字符串"I am a st ...

  7. 7-59 翻转单词顺序 (20 分)

    7-59 翻转单词顺序 (20 分) 给定一个字符串,翻转该字符串,翻转时单词中的字符顺序不变.例如,如果字符串为"Hello World",则翻转后为"World He ...

  8. 剑指 Offer 58 - I. 翻转单词顺序 (双指针)

    剑指 Offer 58 - I. 翻转单词顺序 题意: 翻转一个英文句子中单词顺序 解法1 思路: split分割 + 倒序 public static String reverseWords(Str ...

  9. 【剑指offer{40-44}】和为S的连续正数序列、和为S的两个数字、左旋转字符串、翻转单词顺序列、扑克牌顺子

    文章目录 和为S的连续正数序列 题目描述 C++代码 和为S的两个数字 题目描述 C++代码 左旋转字符串 题目描述 C++代码 翻转单词顺序列 题目描述 C++代码 扑克牌顺子 题目描述 C++代码 ...

最新文章

  1. CGLIB代理到底是个什么东西?这是一篇最全的CGLIB大全
  2. CentOS 6.4 配置LAMP 环境 与安装 phpmyadmin
  3. SpringCloud Greenwich(一)注册中心之nacos、Zuul和 gateway网关配置
  4. Lockdown Wheelie项目
  5. vue-day02-vue常用特性
  6. 【Java】函数式接口与Lambda表达式
  7. mybatis使用详解
  8. matlab做班级抽签,matlab抽签程序(含源码)
  9. 【算法动画图解】:安利一款昨天发现的app
  10. eclipse快捷键介绍
  11. latex beamer template
  12. JAVA北京时间转换为世界协调时
  13. 视频号运营玩法;以及视频号引流变现赚钱。丨国仁网络资讯
  14. 翻译:Deep Multimodal Clustering for Unsupervised Audiovisual Learning
  15. 增广拉格朗日函数法(ALM)
  16. 广西软件性能测试,道亨软件承建广西智慧水库标杆项目
  17. 【补充】Linux-2.6.22.6 makefiles.txt翻译
  18. 前端,通过面试去学习,综合(面试总结整理)
  19. 首次使用idea需要配置哪些东西?
  20. 华为7.31笔试(第一题AC、第二题AC、第三题超纲)

热门文章

  1. C和指针之动态内存分配之编程练习3
  2. C++之namespace和::使用总结
  3. 链表之判断一个链表是否为回文结构(三)
  4. php基础教程 第十步 阶段性知识补充
  5. awb数据怎么计算_白平衡自己主动(AWB)算法---2,颜色计算
  6. linux下网口监控软件_超赞的!Aibaba技术官分享高性能Linux服务器解读笔记
  7. COMA(一): Learning to Communicate with Deep Multi-Agent Reinforcement Learning 论文讲解
  8. python程序题斐波那契数列_Python_经典题_斐波那契数列
  9. 资料分享 | 数学建模竞赛备战大全
  10. 资料分享 | 数据挖掘实例资料分享来袭