数据结构与算法--翻转单词顺序

翻转单词顺序

  • 题目:输入一个英文句子,翻转句子中的单词顺序,但是单词内的字符顺序不变,例如: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的两个数字
下一篇:数据结构与算法–判断扑克牌是否顺子

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/310320.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在.NET Core中用最原生的方式读取Nacos的配置

背景 之前老黄写过一篇《ASP.NET Core结合Nacos来完成配置管理和服务发现》简单介绍了如何让.NET Core程序接入Nacos&#xff0c;之前的SDK里面更多的是对Nacos的Open API进行了封装以及对服务注册和发现的封装。配置这一块当时并没有过多的处理&#xff0c;用起来有时感觉不会…

[Java基础]TreeSet集合概述和特点

练习代码如下: package TreeSetPack;import java.util.TreeSet;public class TreeSetDemo {public static void main(String[] args){TreeSet<Integer> ts new TreeSet<Integer>();ts.add(10);ts.add(40);ts.add(30);ts.add(50);ts.add(20);ts.add(30);for (Inte…

.NET Core下的开源分布式任务调度系统ScheduleMaster-v2.0低调发布

从1月份首次公开介绍这个项目到现在也快4个月了&#xff0c;期间做了一些修修补补整体没什么大的改动。2.0算是发布之后第一个大的版本更新&#xff0c;带来了许多新功能新特性&#xff0c;也修复了一些已知的bug&#xff0c;在此感谢在博客、Issue和QQ群中提出各种意见的朋友&…

[Java基础]自然排序Comparable的使用

代码如下: package ComparablePack;public class Student implements Comparable<Student>{private String name;private int age;public Student() {}public Student(String name, int age) {this.name name;this.age age;}public String getName() {return name;}pu…

数据结构与算法--我们来玩丢手绢(约瑟夫环问题)

我们来玩丢手绢 昨天我们打扑克&#xff0c;今天我们丢手绢丢手绢我们都知道这个游戏&#xff0c;他的由来由约瑟夫 &#xff08;Josephus&#xff09;提出来的 据说著名犹太历史学家Josephus有过以下的故事&#xff1a;在罗马人占领乔塔帕特后&#xff0c;39 个犹太人与Jose…

后端开发都应该了解点接口的压力测试(Apache Bench版)

背景 小A&#xff1a;小B&#xff0c;最近调你的接口老是超时呀&#xff0c;8秒都还没返回结果&#xff0c;是不是有性能问题呀&#xff01;小B &#xff1a;我看看~~类似这样的对话&#xff0c;在现实中是时有发生的&#xff0c;不是特别严重的话&#xff0c;往往大家也不会去…

数据结构与算法--这个需求很简单怎么实现我不管(发散思维)

发散思维 程序员是一个高危职业&#xff0c;最近动不动就听到谁谁谁猝死&#xff0c;谁谁谁过劳晕倒&#xff0c;所以面对奇葩问题&#xff0c;我们要淡定&#xff0c; 开发中被产品虐&#xff0c;说的最多的一句话就是这个需求很简单&#xff0c;怎么实现我不管 找工作被面试…

[Java基础]比较器排序Comparator的使用

代码如下: package ComparablePack;public class Student {private String name;private int age;public Student() {}public Student(String name, int age) {this.name name;this.age age;}public String getName() {return name;}public void setName(String name) {this…

手把手教你如何构建 WPF 官方开源框架源代码

本文转自林德熙的博客&#xff08;blog.lindexi.com&#xff09;导语从去年微软就将 WPF 开源了&#xff0c;差不多现在所有 WPF 的源代码都开源了。在学习框架的时候&#xff0c;我会做一些改动&#xff0c;期望能构建一个自己的版本进行测试。但是作为一个特别大的框架&#…

数据结构与算法--再来聊聊数组

再来聊聊数组 这篇我们来总结一下数组相关的一些算法&#xff0c;数组的特点在于我们能通过下标得到对应数据&#xff0c;时间复杂度在O(1)&#xff0c;之前有多篇文章有数组相关的体系&#xff0c;一下来一个归纳&#xff1a; 数据结构与算法–判断扑克牌是否顺子 数据结构…

[Java基础]泛型基础

可变参数的使用&#xff1a; 代码如下: package CanChangePack;import java.util.Arrays; import java.util.List;public class ArgsDemo01 {public static void main(String[] args){List<String> list Arrays.asList("hello","world","jav…

数据结构与算法--二叉树第k个大的节点

二叉树第k个大的节点 二叉树文章列表&#xff1a; 数据结构与算法–面试必问AVL树原理及实现 数据结构与算法–二叉树的深度问题 数据结构与算法–二叉堆&#xff08;最大堆&#xff0c;最小堆&#xff09;实现及原理 数据结构与算法–二叉查找树转顺序排列双向链表 数据…

Istio 中的 Sidecar 注入及透明流量劫持过程详解

图片来源&#xff1a;上海五角场 by Jimmy Song本文基于 Istio 1.5.1 版本&#xff0c;将为大家介绍以下内容&#xff1a;什么是 sidecar 模式和它的优势在哪里。Istio 中是如何做 sidecar 注入的&#xff1f;Sidecar proxy 是如何做透明流量劫持的&#xff1f;流量是如何路由到…

数据结构与算法--求1~n能组成的所有二叉搜索树的排列

给定一个整数n&#xff0c;生成并返回所有N个节点组成并且节点值从1到n互不相同的不同二叉树&#xff0c;可以按照任意顺序 二叉树文章列表&#xff1a; 数据结构与算法–面试必问AVL树原理及实现 数据结构与算法–二叉树的深度问题 数据结构与算法–二叉堆&#xff08;最大…

Java语法基础50题训练(下)

题目1: HashMap集合存储学生对象并遍历。 需求: 创建一个HashMap集合&#xff0c;键是学生对象(Student)&#xff0c;值是居住地(String)。存储多个键值对象&#xff0c;并遍历。 要求: 保证键的唯一性&#xff1a;如果学生对象的成员变量值相同&#xff0c;我们就认为是同一…

用long类型让我出了次生产事故,写代码还是要小心点

昨天发现线上试跑期的一个程序挂了&#xff0c;平时都跑的好好的&#xff0c;查了下日志是因为昨天运营跑了一家美妆top级淘品牌店&#xff0c;会员量近千万&#xff0c;一下子就把128G的内存给爆了&#xff0c;当时并行跑了二个任务&#xff0c;没辙先速写一段代码限流&#x…

Mongodb查询分析器解析

Mongodb查询分析器 动态相关项目中涉及到数据量大和吞吐量的接口&#xff0c;例如关注页面动态&#xff0c;附近动态&#xff0c;这部分数据都是存储在mongodb中&#xff0c;在线上数据中分类两个mongodb集合存储其中关注动态基于扩散写的设计&#xff0c;数据量已经快到 8 亿…

[Java基础]Collections概述和使用

代码如下: package CollectionDemo01;import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List;public class CollectionDemo01 {public static void main(String[] args){List<Integer> list new ArrayList&l…

链路追踪在ERP系统中的应用实践

源宝导读&#xff1a;随着ERP的部署架构越来越复杂&#xff0c;对运维监控、问题排查等工作增加了难度&#xff0c;本文将介绍通过引入链路追踪技术&#xff0c;提高ERP系统问题排查效率&#xff0c;支撑更全面监控系统运行情况的实践过程。一、导读随着ERP的部署架构越来越复杂…