LeetCode6-Z字形变换

简介: LeetCode6-Z字形变换

题目



将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 “LEETCODEISHIRING” 行数为 3 时,排列如下:

L   C   I   
RE T O E S I I G
E   D   H   N


之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“LCIRETOESIIGEDHN”。

请你实现这个将字符串进行指定行数变换的函数:


string convert(string s, int numRows);


示例



输入: s = “LEETCODEISHIRING”, numRows = 4

输出: “LDREOEIIECIHNTSG”

解释:

L     D     R
E   O E   I I
E C   I H   N
T     S     G


分析



方法一:


假如 s = “PAYPALISHIRING”, numRows = 4 (括号里的数字代表这个字符在该字符串的位置)



首先可以确定的是中间斜着的行数(也就是每两个竖列之间的间隔)是gap = numRows - 2 =2


观察可以发现:


第一行和最后一行都是每隔6位取一位 通过观察 ,可以通过(numRows-1)+gap+1得到 其实就是竖着的4个(因为下标从0开始计算,所以应该减一) 加上两个斜着的(gap) 再加上另一列上的1(语言表达能力不太好,希望大家可以看的懂。。。。。) 这样可以计算出首行和尾行的间隔,将这个间隔设为k1,k1 = 6


第二行是1,5,7,11,13 间隔是 +4 +2 +4 +2 … 这个可以两个看作一组,4就是 k2 = k1-i*2 = k1-2 (这里的i是指行数,从0开始计算) ,2可以看作 k1 - k2


第三行是2,4,8,10 间隔是 +2 +4 +2 +4 同样,2是k2 = k1 - i*2 = k1 -4 ,4位k1-k2


验证上面的规律:


s= “PAYPALISHIRING” , numRows = 3 (括号里的数字代表这个字符在该字符串的位置)



gap = numRows - 2 =1


第一行和最后一行都是每隔4位取一位 k1 = (numRows-1)+gap+1 = 3-1+1+1 = 4


第二行是1,3,5,7,9 每次位数增加2 i = 1, +2 +2 +2 +2… k2 = k1-i*2 = k1-2 = 4-2 = 2 后面就可以直接用 k1-k2 然后每次更新k2即可


如果不放心 ,可以另取一个numRows较大的字符串进行测试。


找到规律以后就可以直接编写代码,值得注意的是 这里会有一个边界条件,length == 0或length<=numRows或numRows==1都可以直接输出,不需要进行操作。


方法二:




方法三:

自己体会,这个代码效率是最高的!!!


代码



package com.leetcode.code;
import java.util.ArrayList;
import java.util.List;
/** 
* LeetCode6-Z字形变换 
* 
* 将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
*
* 比如输入字符串为 "LEETCODEISHIRING" 行数为 4 时,排列如下: 
*
* 输入: s = "LEETCODEISHIRING", numRows = 4 
* 输出: "LDREOEIIECIHNTSG" 
* 解释: 
*
* L     D     R 
* E   O E   I I
* E C   I H   N
* T     S     G
* 
*/
public class LeetCode6 {  
  // 方法一   
  public static String convert(String s, int numRows) {   
    int length = s.length();   
    if(length == 0 || length <= numRows || numRows == 1) { 
      return s;     
    }      
    int gap = numRows - 2;   
    String ans = "";     
    int k1 = numRows -1 + gap + 1;    
    for (int i = 0; i < numRows; i++) {    
      int location = 0;     
      if (i==0 || i == numRows - 1) {           
        ans = ans + s.charAt(i);      
        location = i + k1;      
        while (location < length) {    
          ans = ans + s.charAt(location);  
          location = location + k1;      
        }            
      } else {     
        ans = ans + s.charAt(i);    
        int k2 = k1 - i * 2;    
        location  = location + k2 + i;  
        while (location < length) {  
          ans = ans + s.charAt(location);     
          k2 = k1 - k2;            
          location  = k2 + location;        
        }        
      }      
    } 
    return ans;   
  }
    // 方法二  
    public static String convert2(String s, int numRows) { 
      if (numRows < 2) {     
        return s;     
      }     
      List<StringBuilder> rows = new ArrayList<StringBuilder>();  
      for (int i = 0; i < numRows; i++) {    
        rows.add(new StringBuilder());     
      }     
      int i = 0, flag = -1;     
      for (char c : s.toCharArray()) {    
        rows.get(i).append(c);     
          if (i == 0 || i == numRows - 1) {   
            flag = - flag;           
          }          
          i += flag;   
        }       
        StringBuilder result = new StringBuilder();  
        for (StringBuilder row : rows) {   
          result.append(row);    
        }      
        return result.toString();  
    }
    // 方法三  
    public String convert3(String s, int numRows) {  
      if (numRows == 1) {  
         return s;     
      }    
      int step = (numRows - 1) << 1;   
      int len = s.length();      
      char[] ans = new char[len];     
      char[] chars = s.toCharArray(); 
      int index = -1;       
      for (int i = 0; i < numRows; i++) { 
        for (int j = i; j < len; j += step) {  
          ans[++index] = chars[j];       
          if (i != 0 && i != numRows - 1 && step - (i << 1) + j < len) {   
            ans[++index] = chars[step - (i << 1) + j];     
          }           
        }       
      }       
      return new String(ans);  
    }
    public static void main(String[] args) {  
    System.out.println(convert("LEETCODEISHIRING", 4));    
    System.out.println(convert2("LEETCODEISHIRING", 4));   
    System.out.println(convert2("LEETCODEISHIRING", 4)); 
    }
}


小结



  • 方法一是找规律的方法,也是大家普遍啊知道的方法,时间复杂度略高。
  • 方法二的妙处是用flag改变存储的方向,也是该方法的精髓所在。
  • 方法三是一个大佬写的代码,我就不做评价了哈哈哈。


性能上:方法一<方法二<方法三

相关文章
|
4月前
|
存储 人工智能 JSON
别被术语吓跑!零基础大模型微调指南:从“调教”逻辑到实战手册
AI博主手把手教你微调大模型!用大白话拆解LoRA、QLoRA等术语,从原理到实操(数据准备→环境配置→参数设置→效果评估),全程可视化工具推荐,8GB显卡也能跑。让通用AI变身懂你的垂直领域助手!
739 5
|
12月前
|
人工智能 监控 安全
人人都是造梦者:AI时代的创意落地指南
有好想法因为"不会技术"而只能停留在脑海里?如果技术门槛不再是阻碍,你最想实现什么?在发现好想法后,如何落地自己的AI创意?这个过程可能需要哪些东西?本文手把手教你如何让自己的创意落地。
663 16
人人都是造梦者:AI时代的创意落地指南
|
机器学习/深度学习 搜索推荐 算法
学生党狂喜,物理图表动起来!受力分析、光学、电路图等全自动交互
“Augmented Physics”是由卡尔加里大学和香港城市大学研究人员开发的创新工具,利用机器学习将静态物理图表转化为交互式模拟,帮助学生通过操作亲身体验物理现象的变化过程,增强理解、提高兴趣并实现个性化学习。该工具在课堂教学、自主学习和虚拟实验中具有广泛应用前景。论文链接:https://arxiv.org/pdf/2405.18614。
424 40
|
运维 安全 数据挖掘
趋势还是噪声?ADF与KPSS检验结果矛盾时的高级时间序列处理方法
在时间序列分析中,ADF(增广迪基-富勒)和KPSS检验用于评估数据的平稳性。当ADF检验失败而KPSS检验通过时,表明序列具有确定性趋势但整体平稳。
433 25
趋势还是噪声?ADF与KPSS检验结果矛盾时的高级时间序列处理方法
|
机器学习/深度学习 人工智能 算法
Nature:AI也许可以拥有常识,但不是现在
人工智能(AI)的快速发展引发了关于其是否能拥有常识的讨论。尽管AI在特定任务上取得进展,但目前仍缺乏真正的常识理解。常识涉及对物理世界、社会规范和文化背景的理解,难以通过数据和算法完全捕捉。研究人员正通过大规模语言模型和强化学习等方法提升AI的常识能力,但仍面临显著局限性,如对物理世界的直观理解不足、社会文化背景理解欠缺以及常识能力的通用性差等问题。未来,多模态学习和与人类交互有望增强AI的常识能力。
399 20
|
安全 Linux 网络安全
centos7中firewall防火墙的常用命令总结
以上命令集覆盖了 `firewalld`的基本操作,是维护CentOS 7系统安全不可或缺的工具。对于更高级的配置需求或遇到特定问题
474 3
|
数据采集 存储 自然语言处理
基于Python的微博热点李佳琦忒网友话题的评论采集和情感分析的方法,利用情感分析技术对评论进行情感倾向性判断
本文介绍了一种基于Python的方法,用于采集微博热点话题下的评论数据,并运用情感分析技术对这些评论进行情感倾向性判断,进而通过统计分析和可视化技术展示网友对特定话题的情感态度,对品牌或个人形象管理、用户需求发现、舆情监测和危机管理等方面具有重要价值。
606 2
基于Python的微博热点李佳琦忒网友话题的评论采集和情感分析的方法,利用情感分析技术对评论进行情感倾向性判断
|
算法 大数据 网络安全
FP-Growth算法
FP-Growth算法
818 2
|
Ubuntu 机器人 Shell
ubuntu20.04创建ros环境、创建rospackage
至此,我们已经详细讲解了在Ubuntu 20.04上创建ROS环境及ROS包的步骤。这为进一步的机器人软件开发奠定了坚实的基础。
603 1
|
API 项目管理 开发者
PEP是Python改进的关键文档,用于提议新特性和标准化变更
【6月更文挑战第26天】PEP是Python改进的关键文档,用于提议新特性和标准化变更。它们提出功能设计,记录社区决策,建立标准,促进共识,并改进开发流程。PEP是Python不断演进和优化的核心机制,驱动语言的未来发展。**
322 2