字符串的反转以及巧用反转 ------关于反转,看这一篇就足够了

目录

一.本文介绍

二.反转字符串

1.题目描述

2.问题分析

3.代码实现

三.反转字符串 II

1.题目描述

2.问题分析

3.代码实现

三.反转字符串中的单词 I

1.题目描述

2.问题分析

3.代码实现

四.反转字符串中的单词 III

1.题目描述

2.问题分析

3.代码实现

五.仅仅反转字母

1.题目描述

2.问题分析

3.代码实现

六.旋转字符串

1.题目描述

2.问题分析

3.代码实现

七.轮转数组

1.题目描述

2.问题分析

3.代码实现

八.整数反转

1.题目描述

2.问题分析

3.代码实现


一.本文介绍

字符串的反转是一个不算难的问题,单纯的字符串整个反转是十分容易的,有难度的的是局部反转,但进入到局部反转之前,我们需要把字符串的整体反转搞清楚.这篇文章虽然主要介绍了字符串的反转,但是还包含了数组的反转,无论是字符数组和整数数组,都进行了讲解.接下来的一些将从力扣的一些题目由易到难的对字符串的反转问题进行系统化的讲解.

二.反转字符串

1.题目描述

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

力扣:力扣

2.问题分析

对于字符串整体的反转,主要就是把前边的字符和后边的字符进行交换,把索引位置为i的和索引位置为nums.length-i-1的字符进行交换,交换到字符串一半的位置,整个字符串的交换就可以完成.

例如:对如下的长度为奇数的i<nums.length/2  偶数的同样也是i<nums.length/2 ,因此终止条件确定

3.代码实现

    public void reverseString(char[] s) {
        for (int i = 0; i < s.length / 2; ++i) {
            char temp = s[i];
            s[i] = s[s.length - i - 1];
            s[s.length - i - 1] = temp;

        }

    }

三.反转字符串 II

1.题目描述

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

  • 如果剩余字符少于 k 个,则将剩余字符全部反转。
  • 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

力扣:力扣

2.问题分析

这一道题目就涉及了局部反转字符串,对于长度为2k的子字符串,只需要反转前k个字符,这个时候我们需要写一个反转的方法,方法的作用是将闭区间[start,end]的子字符串进行反转,其实和之前反转前部的类似,这个时候开始是从start位置开始,到(start+end)/2的位置结束,注意这个时候等于(start+end)/2的时候是继续循环的,只有当大于的时候,循环才结束,此时索引为i的位置对应索引为end-i+start的位置进行交换(循环终止的条件可以修改为i<(start+end+1)/2,这样和整体反转字符串相统一)

对于2k个子字符串,我们对前k个字符串进行反转,当剩余的字符串的长度不足k个的时候,我们对这剩余的字符串进行反转,这个时候便不需要反转k长度的字符串了.这个时候加一个判断条件,这一题便可以解决了

3.代码实现

    public String reverseStr(String s, int k) {
        char[] arr = s.toCharArray();
        for (int i = 0; i < arr.length; i += 2 * k) {
            if (i + k >= arr.length) {
                reverse(arr, i, arr.length - 1);
            } else {
                reverse(arr, i, i + k - 1);
            }

        }
        return new String(arr);

    }

    //将闭区间[start,end]的子字符串进行反转
    public void reverse(char[] chars, int start, int end) {
        for (int i = start; i <= (end + start) / 2; ++i) {
            char temp = chars[i];
            chars[i] = chars[end - i + start];
            chars[end - i + start] = temp;
        }
    }

三.反转字符串中的单词 I

1.题目描述

给你一个字符串 s ,请你反转字符串中 单词 的顺序。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。

注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

力扣:力扣

2.问题分析

这一题是一道十分综合的题目,对于这种问题我们一般采用双指针的方法进行解决(start,end),来找到一个单词的长度,然后进行反转即可,这道题目主要可以从以下三个步骤来解决:

1.去除多余的空格,单词前导和后导可能存在无意义的空格,例如"  word in use   ",需要把空格去掉,每个单词间也可能存在多个空格,需要把单词间的空格变为一个

2.将整个字符串进行反转

3.将反转后的字符串的每个单词进行反转.也就是找到空格的位置,然后反转start到end的位置

3.代码实现

    public String reverseWords(String s) {
        //去除多余的空格
        StringBuilder sb = reverseSpace(s);
        //将字符串反转
        reverseString(sb, 0, sb.length() - 1);
        //反转每个单词
        reverseEachWord(sb);
        return new String(sb);


    }

    public StringBuilder reverseSpace(String s) {
        int start = 0, end = s.length() - 1;
        while (s.charAt(start) == ' ') start++;
        while (s.charAt(end) == ' ') end--;
        StringBuilder sb = new StringBuilder();
        while (start <= end) {
            if (s.charAt(start) == ' ') {
                sb.append(' ');
                ++start;
                while (s.charAt(start) == ' ') {
                    ++start;
                }
            }
            sb.append(s.charAt(start++));

        }
        return sb;
    }

    public void reverseString(StringBuilder sb, int start, int end) {
        while (start < end) {
            char temp = sb.charAt(start);
            sb.setCharAt(start, sb.charAt(end));
            sb.setCharAt(end, temp);
            ++start;
            --end;
        }
    }

    public void reverseEachWord(StringBuilder sb) {
        int start = 0, end = 0;
        while (end < sb.length()) {
            while (end < sb.length() && sb.charAt(end) != ' ') {
                ++end;
            }
            reverseString(sb, start, end - 1);
            end += 1;
            start = end;

        }

    }

四.反转字符串中的单词 III

1.题目描述

给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。

力扣:力扣

2.问题分析

这一道题相对于上一道题就很简单了,还是使用双指针(start,end)每次只需要找到空格,然后将start到end-1的位置的子字符串进行反转,然后一直到字符串的末尾,具体的实现参考代码

3.代码实现

    public String reverseWords(String s) {
        char[] chars = s.toCharArray();
        int start = 0, end = 0;
        while (end < chars.length) {
            while (end < chars.length && chars[end] != ' ') {
                end++;
            }
            reverse(chars, start, end - 1);
            end = end + 1;
            start = end;

        }
        return new String(chars);


    }

    public void reverse(char[] s, int start, int end) {
        while (start < end) {
            char temp = s[start];
            s[start] = s[end];
            s[end] = temp;
            start++;
            end--;
        }
        
    }

五.仅仅反转字母

1.题目描述

给你一个字符串 s ,根据下述规则反转字符串:

  • 所有非英文字母保留在原有位置。
  • 所有英文字母(小写或大写)位置反转。

返回反转后的 s

力扣:力扣

2.问题分析

这一道题和普通的完全反转字符串其实就多了一个条件的判断,就是我们双指针(start,end)一定要落到字母字符的时候才能进行反转,并且当start>=end的时候立即终止反转,此时得到的结果就是最终的答案.

3.代码实现

    public String reverseOnlyLetters(String s) {
        if (s == "")
            return s;
        char[] arr = s.toCharArray();
        int start = 0, end = s.length() - 1;
        while (start < end) {
            while (arr[start] < 'A' || (arr[start] > 'Z' && arr[start] < 'a')
                    || arr[start] > 'z') {
                start++;
                if (start >= end) {
                    return new String(arr);
                }
            }
            while (arr[end] < 'A' || (arr[end] > 'Z' && arr[end] < 'a')
                    || arr[end] > 'z') {
                end--;
                if (start >= end) {
                    return new String(arr);
                }
            }
            char temp = arr[start];
            arr[start] = arr[end];
            arr[end] = temp;
            start++;
            end--;

        }
        return new String(arr);

    }

六.旋转字符串

1.题目描述

给定两个字符串, s 和 goal。如果在若干次旋转操作之后,s 能变成 goal ,那么返回 true 。

s 的 旋转操作 就是将 s 最左边的字符移动到最右边。 

  • 例如, 若 s = 'abcde',在旋转一次之后结果就是'bcdea' 。

力扣:力扣

2.问题分析

这一道题一行代码搞定,s进行若干次旋转是否能得到goal,其实就是把s拼接到s的后面,其中一定包含旋转之后的子字符串,这个时候判断拼接之后的字符串是否包含goal即可.

3.代码实现

    public boolean rotateString(String s, String goal) {
        return s.length()==goal.length()&&(s+s).contains(goal);
    }

七.轮转数组

1.题目描述

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

力扣:力扣

2.问题分析

这是一道十分意思的题目,数组元素向右轮转k个位置,当k>=nums.length的时候,其实就轮转了k%nums.length次,所以我们先这样处理k=k%nums.length.

然后就是这一道题目有意思的地方:

1.我们先反转整个数组

2.我们再反转[0,k-1]的元素

3.最后我们反转[k,nums.length-1]的元素

这个时候我们得到的就是答案了,具体为什么我们借用下面的图形来说明.

nums = "----->-->"; k =3
result = "-->----->";

reverse "----->-->" we can get "<--<-----"
reverse "<--" we can get "--><-----"
reverse "<-----" we can get "-->----->"

3.代码实现

    public void rotate(int[] nums, int k) {
        k=k%nums.length;
        reverse(nums,0,nums.length-1);
        reverse(nums,0,k-1);
        reverse(nums,k,nums.length-1);

        

    }
    public void reverse(int[] nums,int start,int end){
        while(start<end){
            int temp=nums[start];
            nums[start]=nums[end];
            nums[end]=temp;
            start++;
            end--;
        }
    }

​

八.整数反转

1.题目描述

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [−231,  231 − 1] ,就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)。

力扣:力扣

2.问题分析

这一道题其实是很简单的,每一次需要将num乘以10加上x的最后一位,再将x的最后一位去掉,最主要的就是如何判断反转后的是否超过了32 位的有符号整数的范围,这个时候题目是要求我们返回0的,其实我们只需要在每次num*10之前判断是否num < Integer.MIN_VALUE / 10 || num > Integer.MAX_VALUE / 10 ,这样在之后的这样之后×10之后一定就不会超过最大的范围了

3.代码实现

    public int reverse(int x) {
        int num = 0;
        while (x != 0) {
            //判断num是否超过了32位有符号整数的范围
            if (num < Integer.MIN_VALUE / 10 || num > Integer.MAX_VALUE / 10) {
                return 0;
            }
            num *= 10;
            num += x % 10;
            x /= 10;

        }
        return num;

    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Python入门第三十五天】Python丨文件打开

在服务器上打开文件 假设我们有以下文件&#xff0c;位于与 Python 相同的文件夹中。 demofile.txt Hello! Welcome to demofile.txt This file is for testing purposes. Good Luck!如需打开文件&#xff0c;请使用内建的 open() 函数。 open() 函数返回文件对象&#xff…

Linux驱动开发——串口设备驱动

Linux驱动开发——串口设备驱动 一、串口简介 串口全称叫做串行接口&#xff0c;通常也叫做 COM 接口&#xff0c;串行接口指的是数据一个一个的顺序传输&#xff0c;通信线路简单。使用两条线即可实现双向通信&#xff0c;一条用于发送&#xff0c;一条用于接收。串口通信距…

基于uniapp+u-view开发小程序【技术点整理】

一、上传图片 1.实现效果&#xff1a; 2.具体代码&#xff1a; <template><view><view class"imgbox"><view>职业证书</view><!-- 上传图片 --><u-upload :fileList"fileList1" afterRead"afterRead"…

C语言蓝桥杯刷题:修剪灌木

题目链接 解题思路&#xff1a; 本题需要注意的是树是白天长&#xff0c;然后爱丽丝傍晩对某棵树进行修剪&#xff0c;也就是说树高度是可能在白天达到最大值而在傍晩变成0。我一开始也有一个误区&#xff0c;以为是要修剪的那棵树当天就变成0而不能生长&#xff0c;其实是先…

vue后台管理系统

后面可参考下&#xff1a;vue系列&#xff08;三&#xff09;——手把手教你搭建一个vue3管理后台基础模板 以下代码项目gitee地址 文章目录1. 初始化前端项目初始化项目添加加载效果配置 vite.config.js2. 使用路由安装路由配置路由配置别名和跳转安装pathvite.config.jsjsco…

C++类和对象(上篇)

目录 1.类的定义 2.类的访问限定符及封装 2.1类的访问限定符 2.2封装 3.类的作用域 4.类的实例化 5.类的大小 6.this 指针 1.类的定义 class className {// 类体&#xff1a;由成员函数和成员变量组成}; // 一定要注意后面的分号 class为定义类的关键字&#xff0c;Clas…

Golang每日一练(leetDay0012)

目录 34. 查找元素首末位置 Find-first-and-last-position-of-element-in-sorted-array &#x1f31f;&#x1f31f; 35. 搜索插入位置 Search Insert Position &#x1f31f; 36. 有效的数独 Valid Sudoku &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 …

VsCode SSH远程连接服务器【内网穿透公网连接】

文章目录1.前言2.VS code的安装和设置2.1 VS code的下载安装2.2 OpenSSH的启用2.3 为VS code配置ssh2.4 局域网内测试VS code的ssh连接2.5 Cpolar下载安装3.Cpolar端口设置3.1 Cpolar云端设置3.2 Cpolar本地设置4.公网访问测试5.结语1.前言 记得笔者小时候看电视&#xff0c;看…

【安全与风险】密码学介绍

密码学介绍密码历史密码换位&#xff08;Transposition&#xff09;与置换&#xff08;Substitution&#xff09;替换密码&#xff08;Substiution Cipher&#xff09;凯撒密码 &#xff08;100BC 公元前100年&#xff09;移位密码破坏替换密码维吉尼亚密码现代密码学核心原理从…

TCP三次握手/四次挥手

TCP三次握手 任何基于TCP的应用&#xff0c;在发送数据之前&#xff0c;都需要由TCP进行“三次握手”建立连接示意图 第一次握手&#xff1a;客户端PC发送一个SYN位置1&#xff08;SYN1代表请求服务端建立连接&#xff09;的TCP报文发送给要建立TCP连接的Server&#xff0c;此…

23种设计模式

参考链接&#xff1a; 【狂神说Java】通俗易懂的23种设计模式教学&#xff08;停更&#xff09;_哔哩哔哩_bilibili 23种设计模式【狂神说】_狂神说设计模式_miss_you1213的博客-CSDN博客 1. 单例模式 参考链接&#xff1a; 【狂神说Java】单例模式-23种设计模式系列_哔哩哔哩…

Linux(网络基础---网络层)

文章目录0. 前言1. IP协议1-1 基本概念1-2 协议头格式2. 网段划分2-1 基本概念2.2 IP地址分五大类2-3 特殊的IP地址2-4 IP地址的数量限制2-5 私有IP地址和公网IP地址2-6 路由0. 前言 前面我们讲了&#xff0c;应用层、传输层&#xff1b;本章讲网络层。 应用层&#xff1a;我…

GPT-4是个编程高手,真服了!

上周给大家发了一个GPT-4教数学的介绍&#xff0c;很多人都被震撼了&#xff0c;感觉有可能在教育行业引发革命。它在编程领域表现如何&#xff1f;先不说能否替代程序员&#xff0c;这个还有待更多的测试和反馈&#xff0c;我想先试试它能不能像教数学那样教编程。我找了个Jav…

Docker的可视化界面工具

Docker的可视化界面工具1. Portainer1.1 Introduction1.1.1 Official1.2 Download And Deploy1.3 Dashboard1.3.1 Dashboard2. Shipyard2.1 Introduction2.1.1 Character2.1.2 Official2.2 Download And Deploy2.2.1 脚本下载镜像2.2.2 执行脚本2.2.2 查看下载的镜像2.3 Dashbo…

“工作三年,跳槽要求涨薪50%”,合理吗?

如果问在TI行业涨工资最快的方式是什么&#xff1f;回答最多的一定是&#xff1a;跳槽&#xff01;前段时间&#xff0c;知乎上这样一条帖子引发了不少IT圈子的朋友的讨论 &#xff0c;有网友提问 “程序员跳槽要求涨薪50%过分吗&#xff1f;”截图来源于知乎&#xff0c;如侵删…

【百面成神】多线程基础16问,你能坚持到第几问

前 言 &#x1f349; 作者简介&#xff1a;半旧518&#xff0c;长跑型选手&#xff0c;立志坚持写10年博客&#xff0c;专注于java后端 ☕专栏简介&#xff1a;纯手打总结面试题&#xff0c;自用备用 &#x1f330; 文章简介&#xff1a;多线程最基础、重要的16道面试题 文章目…

【百面成神】Redis基础11问,你能坚持到第几问

前 言 &#x1f349; 作者简介&#xff1a;半旧518&#xff0c;长跑型选手&#xff0c;立志坚持写10年博客&#xff0c;专注于java后端 ☕专栏简介&#xff1a;纯手打总结面试题&#xff0c;自用备用 &#x1f330; 文章简介&#xff1a;Redis最基础、重要的11道面试题 文章目录…

AI 未来已至,向量数据库站在新的节点上

“AI 的 iPhone 时刻已经到来。” 在刚刚结束的 NVIDIA GTC Keynote 中&#xff0c;这句话被 NVIDIA CEO 黄仁勋反复提及&#xff0c;长达 1 个多小时的分享中&#xff0c;生成式 AI 相关的内容占据了绝大部分比重。他表示&#xff0c;生成式 AI 的火热能力为企业带来了挑战&a…

2022/3/22 从CV方向角度 —快速解读Nvidia 2023GTC

GTC分享内容和个人看法 3月21号11点&#xff0c;Nvidia开启了GTC主题演讲&#xff0c;这些年英伟达加速库的发展和对AI的投入应用&#xff0c;不难看出掌握GPU加速计算技术的N家肯定是宣扬AI方向的产品和生产工具&#xff0c;下面我将简要汇总下演讲的内容&#xff0c;和从我自…

Java语言-----类与对象的秘密

目录 前言 一、类与对象的介绍 二、类的实例化 三.类与对象的使用方法 3.1对象的初始化 3.2内存显示图 四.this的使用方法 总结 &#x1f63d;个人主页&#xff1a; tq02的博客_CSDN博客-C语言,Java领域博主 &#x1f308;理想目标&#xff1a;努力学习&#xff0c;向Java进…