• LeetCode


    题目

    URL:https://leetcode.com/problems/zigzag-conversion

    解法

    一、程序员

    对于一个程序员来说,肯定是想模拟 ZigZag 的数组,再根据 ZigZag 的位置一行一行的输出。

    ZigZag 模拟很简单,首先得出行数和列数,之后模拟 ZigZag 方式:先向下,后对角,都是遇到边界停下。

        public String convert(String s, int numRows) {
            if (numRows == 1) return s;
    
            int step = 2 * numRows - 2;
            int columnRows = (s.length() / step + 1) * (step / 2);
            char[][] c = new char[numRows][columnRows];
    
            int count = 0, i = 0, j = 0;
            boolean isDown = true;
            while (count < s.length()) {
                c[i][j] = s.charAt(count);
                count++;
    
                if (i == numRows - 1) {
                    isDown = false;
                } else if (i == 0) {
                    isDown = true;
                }
    
                if (isDown) {
                    i++;
                } else {
                    i--;
                    j++;
                }
            }
    
            StringBuilder result = new StringBuilder();
            for (int row = 0; row < c.length; row++) {
                for (int col = 0; col < c[0].length; col++) {
                    if (c[row][col] != 'u0000') result.append(c[row][col]);
                }
            }
            return result.toString();
        }

    程序员,时间复杂度O(n2),运行时间约为 90 ms

    二、数学家

    必然有规律可以输出。

    首先观察分组,每组数量是 2 * numRows - 2,对应的是一个纵列和对角列(当然不包括下一个纵列的头)。

    其次观察分对,在分组中可以发现,第一个元素没有配对;第二个元素和倒数第一个元素配对;第三个元素和倒数第二个元素配对;······;中间有个元素,即 numRows -1 行的元素,是没有配对的,直接输出。

    上面的思想完成之后,就可以具体实现:

    1. 输出第一列;
    2. 确定每个分组中每个分对的起始下标,输出分对元素;
    3. 输出最后一列。
        public String convert(String s, int numRows) {
            if (numRows == 1) return s;
    
            int step = 2 * numRows - 2;
            StringBuilder result = new StringBuilder();
            for (int i = 0; i < s.length(); i += step) {
                result.append(s.charAt(i));
            }
            for (int line = 1; line < numRows - 1; line++) {
                for (int i = line; i < s.length(); i = i + step) {
                    result.append(s.charAt(i));
                    if (i + (numRows - line - 1) * 2 < s.length()) {
                        result.append(s.charAt(i + (numRows - line - 1) * 2));
                    }
                }
            }
            for (int i = numRows - 1; i < s.length(); i += step) {
                result.append(s.charAt(i));
            }
    
            return result.toString();
        }

    数学家,时间复杂度O(n2),运行时间约为 40 ms

    总结

    程序员会数学真的是要上天。程序员应该学好数学,数学是计算机的基础。利用数学相关知识,可以优化程序性能。

  • 相关阅读:
    053(九)
    方法的重载
    方法的重写(override / overwrite)
    属性与局部变量的对比
    面向对象基础知识合集:对象的产生、对象的生命周期、内存解析
    使用二维数组打印一个 10 行杨辉三角
    数组中的常见异常: 1. 数组角标越界的异常:ArrayIndexOutOfBoundsExcetion 2. 空指针异常:NullPointerException
    快速排序
    * 数组的冒泡排序的实现
    * 二维数组的使用
  • 原文地址:https://www.cnblogs.com/Piers/p/7153001.html
Copyright © 2020-2023  润新知