ARTS打卡第五周

Algorithm:Leetcode 6. Z 字形变换

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

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

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

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

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

string convert(string s, int numRows);

示例 1:

输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"

示例 2:

输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"

解释:

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

思路一:
拿到题目的首先思路就是用一个二维矩阵来存储Z字形变换的结果。用二维矩阵需要知道三个要素:行数、列数和每个字母在矩阵中的位置。行数是输入的,列数需要根据字符串的长度来计算,通过移动行和列的索引来确定字母在矩阵中的位置。

public String convert(String s, int numRows) {
        if(numRows == 0) {
            return null;
        }
        if(numRows == 1) {
            return s;
        }

        // 计算列数
        int tempLen = 0;
        int numCols=0;
        while(tempLen < s.length()) {
            if(numCols % (numRows-1) == 0) {
                tempLen += numRows;
            } else {
                tempLen += 1;
            }
            numCols++;
        }

        char[][] ans = new char[numRows][numCols];
        boolean down = false;
        int row=0;
        int col=0;
        // 遍历字符串
        for(int j=0; j<s.length(); j++) {
            System.out.println("row:"+ row + " col:" + col);
            ans[row][col] = s.charAt(j);
            // 改变方向
            if(row == 0 || row == numRows-1) {
                down = !down;
            }
            if(down) {
                row++;
            } else {
                row--;
                col++;
            }
        }

        StringBuilder sb = new StringBuilder();
        for(row=0; row<numRows; row++) {
            for(col=0; col<numCols; col++) {
                if(ans[row][col] != 0) {
                    sb.append(ans[row][col]);
                }
            }
        }
        return sb.toString();
    }

时间复杂度:遍历字符串是O(n),遍历二维数组是O(numRows*numCols) > O(n)。

思路二:
由于思路一中二维矩阵存储中有很多单元是无用的,输出结果前还需要将其过滤掉,增加了时间复杂度。我们可以将二维矩阵中的无效单元压缩掉。虽然结果看上去是Z字形,但实际我们不需要按Z字形输出,所以没必要按Z字形存储,可以将列存储得更紧凑些。

public String convert(String s, int numRows) {
        if(numRows == 0) {
            return null;
        }
        if(numRows == 1) {
            return s;
        }
        numRows = Math.min(s.length(), numRows);
        StringBuilder[] ans = new StringBuilder[numRows];
        for(int i=0; i<numRows; i++) {
            ans[i] = new StringBuilder();
        }

        boolean down = false;
        int row=0;
        // 遍历字符串
        for(int j=0; j<s.length(); j++) {
            // 改变方向
            if(row == 0 || row == numRows-1) {
                down = !down;
            }
            ans[row].append(s.charAt(j));
            row += down ? 1 : -1;
        }

        StringBuilder sb = new StringBuilder();
        for(row=0; row<numRows; row++) {
            sb.append(ans[row]);
        }
        return sb.toString();
    }

时间复杂度:需要遍历一遍字符串,所以是O(n)
空间复杂度:需要2n个额外存储空间,所以是O(n)

Review: The Huawei Ban — How the Trade War is Hurting Tech

美国对华为的禁令会造成什么影响?对华为来说,硬件不是太大的问题,但是想替换掉Android系统,还是很难的。制作一个新的系统,对华为来说不是不可能,事实上,华为已经有了自己的操作系统。最大的挑战是建立一个生态系统。
坦白地说,并没有证据证明华为的手机相比其他Android手机有更大的安全问题。这次禁令明显就是美中之间贸易战的结果。

Ultimately, we’re trading innovation and technological advancement for national pride, an economic tug-of-war, and intellectual property discrepancies.
最终,我们正在用创新和技术进步来换取民族自豪感、(赢得)经济拔河(的胜利)和(弥补)知识产权的差异

尽管华为在美国的市场份额不大,但仍然和美国企业形成了竞争关系。从技术角度来说,这种竞争促进了前沿技术的进步(面部识别、屏幕下指纹识别、弹出式相机和折叠手机等)。如果没有这种竞争关系,企业将不会再以如此快的频率更新自己的产品,垄断现象会加剧,科技进步将会停止。竞争是工业创新的关键驱动力。

With better technology, humanity blossoms
有了更好的技术,人类才会繁荣

Under what conditions, then, should we be okay with sacrificing this development? How much do we value technology’s ability to improve the well-being of individuals and societies?
那么,在什么条件下,我么可以牺牲这种发展呢?我们在多大程度上重视技术改善个人和社会福祉的能力呢? PS:有道翻译的太好了!!!

If the blacklist is implemented at much larger scale, to what extent can such political actions obstruct the growth of tech and, in effect, the enhancement of quality of life?
如果黑名单被大规模实施,这种政治行为会在多大程度上阻碍科技的发展,并在实质上阻碍生活质量的提高?

Keeping this question in mind when considering global affairs is imperative, since ultimately, we are the people who are affected.

Tip: Shell脚本中如何获取当前目录?

#!/bin/bash
cur_dir=$(dirname $0)
cd $cur_dir
dir_path=$(pwd)

说明:
$0 是Shell中的特殊变量,表示当前脚本的文件名
$(dirname $0) 获取当前脚本所在的目录,可能是绝对路径,也可能是相对路径
cd 命令进入脚本所在目录
$(pwd) 获取当前目录的绝对路径

上述脚本可以简写成

#!/bin/bash
dir_path=$(cd `dirname $0`; pwd)

附录:Shell中的特殊变量

$$ 
Shell本身的PID(ProcessID) 
$! 
Shell最后运行的后台Process的PID 
$? 
最后运行的命令的结束代码(返回值) 
$- 
使用Set命令设定的Flag一览 
$* 
所有参数列表。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 
$@ 
所有参数列表。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。 
$# 
添加到Shell的参数个数 
$0 
Shell本身的文件名 
$1~$n 
添加到Shell的各参数值。$1是第1参数、$2是第2参数…。 

Share: 读硕士和博士的短短几年真正学到的是什么?

Intellectual Skills 智力

Communication Skills 沟通能力

Personality Characteristics 人格

Habits Of Work 工作习惯

Mechanical Skills 动手能力

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值