轮转数组问题:如何实现数组“整体逆序,内部有序”?“三步转换法”妙转数组 (二)

简介: 这是一个关于字符串处理的问题,要求将一句话中的单词顺序倒置,但保持单词内部的字符顺序不变。例如,"I like beijing." 变为 "beijing. like I"。解决方法可以分为三个步骤:分块、内部逆序和整体逆序。代码示例使用C语言实现,通过指针和while循环操作字符串数组。最终总结提到,无论先逆置哪个部分,只要确保所有部分都逆置过,结果都是相同的。

轮转数组问题:如何实现数组“整体逆序,内部有序”?“三步转换法”妙转数组(一)+   https://developer.aliyun.com/article/1518463?spm=a2c6h.13148508.setting.14.73ba4f0eD6sgs2


三、拓展:倒置字符串


这道题是上面三步转换法非常合适的一个变式。


1. 题干


牛客网链接  


https://www.nowcoder.com/questionTerminal/8869d99cf1264e60a6d9eff4295e5bab


将一句话的单词进行倒置,标点不倒置。

比如 "I like beijing.",经过处理后变为:"beijing. like I"

(字符串长度不超过100)



2. 思路


这也是“整体逆序,内部有序”的典例:我们将字符串内容按单词分块,单词在整个句子中的顺序发生变化,但单词还是单词,它内部的字母顺序并没有发生变化。

当我们明白这一点,接下来的事情也许会好办许多。



3. 代码


这里我们采用指针+while循环的方式来对字符串数组进行操作。这里是单纯的倒置,不存在向左或向右轮转的方向问题,因此方向这里就不用考虑了。

此外还有一些细节方面需要注意,如scanf读不了空格,当字符串中需要空格的时候,最好用gets()函数读取


//将逆置操作封装成函数
void reverse(char* left, char* right)
{
    //加了两句断言
    assert(left);
    assert(right);
 
    while (left < right)
    {
        char tmp = *left;
        *left = *right;
        *right = tmp;
        left++;
        right--;
    }
}
 
int main()
{
    char arr[101] = { 0 };
    //注意要用gets()函数,因为它可以读入空格
    gets(arr);
 
    //用指针来操作数组
    char* cur = arr;
 
    //逆序每个单词
    while (*cur)
    {
        char* start = cur;
        char* end = cur;
        while (*end != ' ' && *end != '\0')
        {
            end++;
        }
        reverse(start, end - 1);
        if (*end != '\0')
            cur = end + 1;
        else
            cur = end;
    }
 
    //逆序整个字符串
    int len = strlen(arr);
    reverse(arr, arr + len - 1);
 
    printf("%s\n", arr);
 
    return 0;
}






四、总结


  1. 三步逆置:将数组分块,块内元素先分别逆置,最后再整体逆置。若无轮转顺序要求,则不需要考虑先逆置数组中的哪一块内的元素。
  2. 本文详细介绍了三步逆置法在倒置字符串和整型数组中的应用,以及两种代码实现。在倒置字符串时我们不需要考虑轮转顺序,只要达到逆置的结果即可,该代码是用指针+区间划分的思想实现的,我们用了while循环来控制。
  3. 在轮转数组的引例中,题目要求的向右轮转,我们就先将右边的k个元素逆置,再将剩下的左边(n-k)个元素逆置,最后整体逆置。虽然本文似乎有强调轮转方向的差别,但其实在数组整体逆置之前,先逆置内部哪部分是并不影响结果的,只要保证每个部分的内部都逆置过了即可。先逆置左边的(n-k)个,再逆置右边的k个,最后再整体逆置,达到的效果是一样的。强调方向仅仅是便于一些同学理解。






相关文章
|
7月前
【变态面试题】【两种解法】不能创建临时变量(第三个变量),实现两个数的交换
【变态面试题】【两种解法】不能创建临时变量(第三个变量),实现两个数的交换
56 0
【变态面试题】【两种解法】不能创建临时变量(第三个变量),实现两个数的交换
|
5月前
|
存储 算法 搜索推荐
|
7月前
|
存储 算法
轮转数组问题:如何实现数组“整体逆序,内部有序”?“三步转换法”妙转数组(一)
这篇内容讲述了数组向右轮转k个位置的问题,主要分为两种解决思路。第一种是“轮转k次法”,直接在原数组上操作,每次循环k次,将数组末尾元素移到开头,时间复杂度为O(N*K),效率较低。第二种是“额外数组法”,使用额外数组存储部分元素,然后移动原数组元素,最后归还额外数组元素,时间复杂度和空间复杂度均为O(N)。文章还介绍了更高效的“三步转换法”,通过三次逆序操作实现数组轮转,分别是逆置后k个元素、逆置前n-k个元素以及整体逆置,这种方法时间复杂度为O(N)且空间复杂度为O(1)。
86 1
|
7月前
链表中涉及“快慢指针”的编程题—“返回中间节点”
链表中涉及“快慢指针”的编程题—“返回中间节点”
62 0
|
容器
List特点和遍历方式及增长因子论证和去重原理和LinkedList特点
List特点和遍历方式及增长因子论证和去重原理和LinkedList特点
39 0
|
前端开发
前端学习案例1-数组反序&排序&乱序的方法
前端学习案例1-数组反序&排序&乱序的方法
82 0
前端学习案例1-数组反序&排序&乱序的方法
数据结构与算法__08--霍夫曼树二叉树遍历:1.写在节点类中,在上层调用;2.写在主函数中一次性整体完成
霍夫曼树二叉树遍历:1.写在节点类中,在上层调用;2.写在主函数中一次性整体完成
L2-002 链表去重 (25 分)(结构体模拟)
L2-002 链表去重 (25 分)(结构体模拟)
143 0