阿俊带你用Kotlin刷算法(二)

本系列通过JavaKotlin这两种语言来解决力扣上面的算法题,由于本人算法菜鸟一枚,可能部分题目并不是最优题解,希望能和各位大神共同讨论~

阿俊带你用Kotlin刷算法(一)

阿俊带你用Kotlin刷算法(二)

项目的GitHub:Algorithm

寻找两个正序数组的中位数(Median of Two Sorted Arrays)

难度:困难

链接:Median of Two Sorted Arrays

代码

Java

/**
 * Created by TanJiaJun on 2021/6/9.
 * 4. 寻找两个正序数组的中位数(Median of Two Sorted Arrays)
 * 难度:困难
 *
 * @see <a href="https://leetcode-cn.com/problems/median-of-two-sorted-arrays/">Median of Two Sorted Arrays</a>
 */
class MedianOfTwoSortedArrays {

    public static void main(String[] args) {
        // 示例一
        System.out.println("示例一:");

        int[] firstNumbers = {1, 3};
        int[] secondNumbers = {2};
        System.out.println(findMedianSortedArrays(firstNumbers, secondNumbers));

        System.out.print("\n");

        // 示例二
        System.out.println("示例二:");

        int[] thirdNumbers = {1, 2};
        int[] fourthNumbers = {3, 4};
        System.out.println(findMedianSortedArrays(thirdNumbers, fourthNumbers));

        System.out.print("\n");

        // 示例三
        System.out.println("示例三:");

        int[] fifthNumbers = {0, 0};
        int[] sixthNumbers = {0, 0};
        System.out.println(findMedianSortedArrays(fifthNumbers, sixthNumbers));

        System.out.print("\n");

        // 示例四
        System.out.println("示例四:");

        int[] seventhNumbers = {};
        int[] eightNumbers = {1};
        System.out.println(findMedianSortedArrays(seventhNumbers, eightNumbers));

        System.out.print("\n");

        // 示例五
        System.out.println("示例五:");

        int[] ninthNumbers = {2};
        int[] tenthNumbers = {};
        System.out.println(findMedianSortedArrays(ninthNumbers, tenthNumbers));
    }

    /**
     * 双指针
     * 时间复杂度:O(m+n),其中m是数组num1的长度,n是数组num2的长度
     * 空间复杂度:O(m+n),其中m是数组num1的长度,n是数组num2的长度
     *
     * @param firstNumbers  第一个数组
     * @param secondNumbers 第二个数组
     * @return 结果
     */
    public static double findMedianSortedArrays(int[] firstNumbers, int[] secondNumbers) {
        int len1 = firstNumbers.length;
        int len2 = secondNumbers.length;
        // 合并后的数组的索引
        int index = 0;
        // 第一个数组的指针,下面用i指针描述
        int i = 0;
        // 第二个数组的指针,下面用j指针描述
        int j = 0;
        // 合并两个数组
        // 创建一个大小是两个数组长度之和的数组
        int[] arrays = new int[len1 + len2];
        while (i < len1 || j < len2) {
            if (i == len1) {
                // 如果第一个数组遍历完毕后,就继续遍历第二个数组
                arrays[index++] = secondNumbers[j++];
            } else if (j == len2) {
                // 如果第二个数组遍历完毕后,就继续遍历第一个数组
                arrays[index++] = firstNumbers[i++];
            } else if (firstNumbers[i] < secondNumbers[j]) {
                // 如果第一个数组的元素小于第二个数组的元素,就将第一个数组中的该元素添加到合并后的新数组,同时将i指针向右移动一格
                arrays[index++] = firstNumbers[i++];
            } else {
                // 如果第一个数组的元素大于第二个数组的元素,就将第二个数组中的该元素添加到合并后的新数组,同时将j指针向右移动一格
                arrays[index++] = secondNumbers[j++];
            }
        }
        // 找出数组的中位数
        double median;
        int length = arrays.length;
        if (length % 2 == 0) {
            // 如果数组长度是偶数,就找出这条中线旁边的两个元素,然后相加之后除以2得到结果
            median = (arrays[length / 2] + arrays[length / 2 - 1]) / 2.0D;
        } else {
            // 如果数组长度是奇数,就找出这条中线对应的元素,该元素就是结果
            median = arrays[length / 2];
        }
        return median;
    }

}

Kotlin

/**
 * Created by TanJiaJun on 2021/6/13.
 * 4. 寻找两个正序数组的中位数(Median of Two Sorted Arrays)
 * 难度:困难
 *
 * @see <a href="https://leetcode-cn.com/problems/median-of-two-sorted-arrays/">Median of Two Sorted Arrays</a>
 */
object MedianOfTwoSortedArraysKotlin {

    @JvmStatic
    fun main(args: Array<String>) {
        // 示例一
        println("示例一:")

        val firstNumbers = intArrayOf(1, 3)
        val secondNumbers = intArrayOf(2)
        println(findMedianSortedArrays(firstNumbers, secondNumbers))

        print("\n")

        // 示例二
        println("示例二:")

        val thirdNumbers = intArrayOf(1, 2)
        val fourthNumbers = intArrayOf(3, 4)
        println(findMedianSortedArrays(thirdNumbers, fourthNumbers))

        print("\n")

        // 示例三
        println("示例三:")

        val fifthNumbers = intArrayOf(0, 0)
        val sixthNumbers = intArrayOf(0, 0)
        println(findMedianSortedArrays(fifthNumbers, sixthNumbers))

        print("\n")

        // 示例四
        println("示例四:")

        val seventhNumbers = intArrayOf()
        val eightNumbers = intArrayOf(1)
        println(findMedianSortedArrays(seventhNumbers, eightNumbers))

        print("\n")

        // 示例五
        println("示例五:")

        val ninthNumbers = intArrayOf(2)
        val tenthNumbers = intArrayOf()
        println(findMedianSortedArrays(ninthNumbers, tenthNumbers))
    }

    /**
     * 双指针
     * 时间复杂度:O(m+n),其中m是数组num1的长度,n是数组num2的长度
     * 空间复杂度:O(m+n),其中m是数组num1的长度,n是数组num2的长度
     *
     * @param nums1 第一个数组
     * @param nums2 第二个数组
     * @return 结果
     */
    private fun findMedianSortedArrays(nums1: IntArray, nums2: IntArray): Double {
        val size1 = nums1.size
        val size2 = nums2.size
        // 合并后的数组的索引
        var index = 0
        // 第一个数组的指针,下面用i指针描述
        var i = 0
        // 第二个数组的指针,下面用j指针描述
        var j = 0
        // 合并两个数组
        // 创建一个大小是两个数组长度之和的数组
        val arrays = IntArray(size1 + size2)
        while (i < size1 || j < size2) {
            when {
                // 如果第一个数组遍历完毕后,就继续遍历第二个数组
                i == size1 -> arrays[index++] = nums2[j++]
                // 如果第二个数组遍历完毕后,就继续遍历第一个数组
                j == size2 -> arrays[index++] = nums1[i++]
                // 如果第一个数组的元素小于第二个数组的元素,就将第一个数组中的该元素添加到合并后的新数组,同时将i指针向右移动一格
                nums1[i] < nums2[j] -> arrays[index++] = nums1[i++]
                // 如果第一个数组的元素大于第二个数组的元素,就将第二个数组中的该元素添加到合并后的新数组,同时将j指针向右移动一格
                else -> arrays[index++] = nums2[j++]
            }
        }
        // 找出数组的中位数
        val size = arrays.size
        return if (size % 2.0 == 0.0) {
            // 如果数组长度是偶数,就找出这条中线旁边的两个元素,然后相加之后除以2得到结果
            (arrays[size / 2] + arrays[size / 2 - 1]) / 2.0
        } else {
            // 如果数组长度是奇数,就找出这条中线对应的元素,该元素就是结果
            arrays[size / 2].toDouble()
        }
    }
}

时间复杂度:O(m+n),其中m是数组num1的长度,n是数组num2的长度。

空间复杂度:O(m+n),其中m是数组num1的长度,n是数组num2的长度。

题解

根据题目可知,这两个数组都是正序(从小到大)的,所以我们可以先使用双指针将这两个数组合并成一个数组,注释写得挺详细了,这里就不在赘述了,合并后得到一个大小是两个数组长度之和的新数组,然后我们从这个数组找出中位数,有两种情况:

  • 如果数组长度是偶数,就找出这条中线旁边的两个元素,然后相加之后除以2得到结果。
  • 如果数组长度是奇数,就找出这条中线对应的元素,该元素就是结果。

最长回文子串(Longest Palindromic Substring)

难度:中等

链接:Longest Palindromic Substring

代码

Java

/**
 * Created by TanJiaJun on 2021/6/10.
 * 5. 最长回文子串(Longest Palindromic Substring)
 * 难度:中等
 *
 * @see <a href="https://leetcode-cn.com/problems/longest-palindromic-substring/">Longest Palindromic Substring</a>
 */
class LongestPalindromicSubstring {

    public static void main(String[] args) {
        // 示例一
        System.out.print("示例一:");

        String firstStr = "babad";
        System.out.println(expandAroundCenterLongestPalindrome(firstStr));

        System.out.print("\n");

        // 示例二
        System.out.print("示例二:");

        String secondStr = "cbbd";
        System.out.println(expandAroundCenterLongestPalindrome(secondStr));

        System.out.print("\n");

        // 示例三
        System.out.print("示例三:");

        String thirdStr = "a";
        System.out.println(expandAroundCenterLongestPalindrome(thirdStr));

        System.out.print("\n");

        // 示例四
        System.out.print("示例四:");

        String fourthStr = "ac";
        System.out.println(expandAroundCenterLongestPalindrome(fourthStr));
    }

    /**
     * 方法一:枚举算法
     * 时间复杂度:O(N^3),其中N是字符串的长度
     * 空间复杂度:O(1)
     *
     * @param str 字符串
     * @return 结果
     */
    private static String longestPalindrome(String str) {
        int maxLength = 0;
        String result = "";
        // 枚举所有的元素
        for (int i = 0, iLen = str.length(); i < iLen; i++) {
            for (int j = i + 1, jLen = str.length(); j <= jLen; j++) {
                String substring = str.substring(i, j);
                if (isPalindromeSubstring(substring) && substring.length() > maxLength) {
                    maxLength = substring.length();
                    result = substring;
                }
            }
        }
        return result;
    }

    /**
     * 判断字符串是否为回文串
     *
     * @param str 字符串
     * @return 结果
     */
    private static boolean isPalindromeSubstring(String str) {
        int length = str.length();
        for (int i = 0; i < length / 2; i++) {
            // 找出该元素作为回文子串的起始位置还有结束位置
            if (str.charAt(i) != str.charAt(length - i - 1)) {
                // 如果其中一个不相同,证明该字符串不是回文串
                return false;
            }
        }
        // 如果字符都相同,证明该字符串是回文串
        return true;
    }

    /**
     * 方法二:中心扩展法(双指针)
     * 时间复杂度:O(N^2),其中N是字符串的长度
     * 空间复杂度:O(1)
     *
     * @param str 字符串
     * @return 结果
     */
    private static String expandAroundCenterLongestPalindrome(String str) {
        int start = 0;
        int end = 0;
        for (int i = 0, length = str.length(); i < length; i++) {
            // 长度是奇数
            int oddLength = getExpandAroundCenterLength(str, i, i);
            // 长度是偶数
            int evenLength = getExpandAroundCenterLength(str, i, i + 1);
            // 得到最大长度
            int maxLength = Math.max(oddLength, evenLength);
            if (maxLength > end - start) {
                // 得到起始位置
                start = i - (maxLength - 1) / 2;
                // 得到结束位置
                end = i + maxLength / 2;
            }
        }
        // 截取对应的字符
        return str.substring(start, end + 1);
    }

    /**
     * 得到中心往两边扩展的长度
     *
     * @param str   字符串
     * @param left  左指针
     * @param right 右指针
     * @return 长度
     */
    private static int getExpandAroundCenterLength(String str, int left, int right) {
        // 找出该元素作为回文子串的起始位置还有结束位置
        while (left >= 0 && right < str.length() && str.charAt(left) == str.charAt(right)) {
            // 如果符合条件,左指针向左移动一格,右指针向右移动一格
            left--;
            right++;
        }
        // 得到长度
        return right - left - 1;
    }
}

Kotlin

import kotlin.math.max

/**
 * Created by TanJiaJun on 2021/6/14.
 * 5. 最长回文子串(Longest Palindromic Substring)
 * 难度:中等
 *
 * @see <a href="https://leetcode-cn.com/problems/longest-palindromic-substring/">Longest Palindromic Substring</a>
 */
object LongestPalindromicSubstringKotlin {

    @JvmStatic
    fun main(args: Array<String>) {
        // 示例一
        print("示例一:")

        val firstStr = "babad"
        println(expandAroundCenterLongestPalindrome(firstStr))

        print("\n")

        // 示例二
        print("示例二:")

        val secondStr = "cbbd"
        println(expandAroundCenterLongestPalindrome(secondStr))

        print("\n")

        // 示例三
        print("示例三:")

        val thirdStr = "a"
        println(expandAroundCenterLongestPalindrome(thirdStr))

        print("\n")

        // 示例四
        print("示例四:")

        val fourthStr = "ac"
        println(expandAroundCenterLongestPalindrome(fourthStr))
    }

    /**
     * 方法一:枚举算法
     * 时间复杂度:O(N^3),其中N是字符串的长度
     * 空间复杂度:O(1)
     *
     * @param str 字符串
     * @return 结果
     */
    private fun longestPalindrome(str: String): String {
        var maxLength = 0
        var result = ""
        // 枚举所有的元素
        str.forEachIndexed { index, _ ->
            for (i in index + 1..str.length) {
                val substring = str.substring(index, i)
                if (isPalindromicSubstring(substring) && substring.length > maxLength) {
                    maxLength = substring.length
                    result = substring
                }
            }
        }
        return result
    }

    /**
     * 判断字符串是否为回文串
     *
     * @param str 字符串
     * @return 结果
     */
    private fun isPalindromicSubstring(str: String): Boolean {
        val length = str.length
        for (i in 0 until length / 2) {
            // 找出该元素作为回文子串的起始位置还有结束位置
            if (str[i] != str[length - i - 1]) {
                // 如果其中一个不相同,证明该字符串不是回文串
                return false
            }
        }
        // 如果字符都相同,证明该字符串是回文串
        return true
    }

    /**
     * 方法二:中心扩展法(双指针)
     * 时间复杂度:O(N^2),其中N是字符串的长度
     * 空间复杂度:O(1)
     *
     * @param str 字符串
     * @return 结果
     */
    private fun expandAroundCenterLongestPalindrome(str: String): String {
        var start = 0
        var end = 0
        str.forEachIndexed { index, _ ->
            // 长度是奇数
            val oddLength = getExpandAroundCenterLength(str = str, left = index, right = index)
            // 长度是偶数
            val evenLength = getExpandAroundCenterLength(str = str, left = index, right = index + 1)
            // 得到最大长度
            val maxLength = max(oddLength, evenLength)
            if (maxLength > end - start) {
                // 得到起始位置
                start = index - (maxLength - 1) / 2
                // 得到结束位置
                end = index + maxLength / 2
            }
        }
        return str.substring(start, end + 1)
    }

    /**
     * 得到中心往两边扩展的长度
     *
     * @param str   字符串
     * @param left  左指针
     * @param right 右指针
     * @return 长度
     */
    private fun getExpandAroundCenterLength(str: String, left: Int, right: Int): Int {
        var l = left
        var r = right
        // 找出该元素作为回文子串的起始位置还有结束位置
        while ((l >= 0 && r < str.length && str[l] == str[r])) {
            // 如果符合条件,左指针向左移动一格,右指针向右移动一格
            l--
            r++
        }
        // 得到长度
        return r - l - 1
    }

}

题解

枚举

// LongestPalindromicSubstringKotlin.kt
/**
 * 方法一:枚举
 * 时间复杂度:O(N^3),其中N是字符串的长度
 * 空间复杂度:O(1)
 *
 * @param str 字符串
 * @return 结果
 */
private fun longestPalindrome(str: String): String {
    var maxLength = 0
    var result = ""
    // 枚举所有的元素
    str.forEachIndexed { index, _ ->
        for (i in index + 1..str.length) {
            val substring = str.substring(index, i)
            if (isPalindromicSubstring(substring) && substring.length > maxLength) {
                maxLength = substring.length
                result = substring
            }
        }
    }
    return result
}

/**
 * 判断字符串是否为回文串
 *
 * @param str 字符串
 * @return 结果
 */
private fun isPalindromicSubstring(str: String): Boolean {
    val length = str.length
    for (i in 0 until length / 2) {
        // 找出该元素作为回文子串的起始位置还有结束位置
        if (str[i] != str[length - i - 1]) {
            // 如果其中一个不相同,证明该字符串不是回文串
            return false
        }
    }
    // 如果字符都相同,证明该字符串是回文串
    return true
}

时间复杂度:O(N^3),其中N是字符串的长度。

空间复杂度:O(1)。

暴力解法,枚举所有元素,要注意的是,由于回文串的特征是正读和反读都一样,例如:abba就是回文串abda就不是回文串了,所以我们只要找到某个字符,并且找到该字符对应索引的字符,只需要遍历该数组长度一半就可以判断该字符串是否为回文串,注释写得挺详细了,这里就不再赘述了。

中心扩展法(双指针)

// LongestPalindromicSubstringKotlin.kt
/**
 * 方法二:中心扩展法(双指针)
 * 时间复杂度:O(N^2),其中N是字符串的长度
 * 空间复杂度:O(1)
 *
 * @param str 字符串
 * @return 结果
 */
private fun expandAroundCenterLongestPalindrome(str: String): String {
    var start = 0
    var end = 0
    str.forEachIndexed { index, _ ->
        // 长度是奇数
        val oddLength = getExpandAroundCenterLength(str = str, left = index, right = index)
        // 长度是偶数
        val evenLength = getExpandAroundCenterLength(str = str, left = index, right = index + 1)
        // 得到最大长度
        val maxLength = max(oddLength, evenLength)
        if (maxLength > end - start) {
            // 得到起始位置
            start = index - (maxLength - 1) / 2
            // 得到结束位置
            end = index + maxLength / 2
        }
    }
    return str.substring(start, end + 1)
}

/**
 * 得到中心往两边扩展的长度
 *
 * @param str   字符串
 * @param left  左指针
 * @param right 右指针
 * @return 长度
 */
private fun getExpandAroundCenterLength(str: String, left: Int, right: Int): Int {
    var l = left
    var r = right
    // 找出该元素作为回文子串的起始位置还有结束位置
    while ((l >= 0 && r < str.length && str[l] == str[r])) {
        // 如果符合条件,左指针向左移动一格,右指针向右移动一格
        l--
        r++
    }
    // 得到长度
    return r - l - 1
}

时间复杂度:O(N^2),其中N是字符串的长度。

空间复杂度:O(1)。

由于回文串的特征是正读和反读都一样,例如:abba就是回文串abda就不是回文串了,所以我们可以从该字符串的中间向两边扩展地遍历,这样就能快速地得到最长的回文子串,要注意的是,因为数组的长度可能是奇数,也可能是偶数,如果是奇数的话,中心点就只有一个;如果是偶数的话,中心点就有两个

Z字形变换(ZigZag Conversion)

难度:中等

链接:ZigZag Conversion

代码

Java

/**
 * Created by TanJiaJun on 2021/6/12.
 * 6. Z字形变换(ZigZag Conversion)
 * 难度:中等
 *
 * @see <a href="https://leetcode-cn.com/problems/zigzag-conversion/">ZigZag Conversion</a>
 */
class ZigZagConversion {

    public static void main(String[] args) {
        // 示例一
        System.out.print("示例一:");

        String firstStr = "PAYPALISHIRING";
        int firstNumRows = 3;
        System.out.println(convert(firstStr, firstNumRows));

        System.out.print("\n");

        // 示例二
        System.out.print("示例二:");

        String secondStr = "PAYPALISHIRING";
        int secondNumRows = 4;
        System.out.println(convert(secondStr, secondNumRows));

        System.out.print("\n");

        // 示例三
        System.out.print("示例三:");

        String thirdStr = "A";
        int thirdNumRows = 1;
        System.out.println(convert(thirdStr, thirdNumRows));
    }

    /**
     * 时间复杂度:O(N),其中N是字符串的长度
     * 空间复杂度:O(N)
     *
     * @param str     字符串
     * @param numRows 行数
     * @return 结果
     */
    private static String convert(String str, int numRows) {
        if (numRows == 1) {
            // 如果只是一行的话,就直接返回该字符串
            return str;
        }
        // 创建长度是行数的StringBuilder数组,并且每个元素都创建StringBuilder对象
        StringBuilder[] stringBuilders = new StringBuilder[numRows];
        for (int i = 0; i < numRows; i++) {
            stringBuilders[i] = new StringBuilder();
        }
        // 索引
        int index = 0;
        // 行数
        int row = 0;
        int length = str.length();
        while (index < length) {
            // 从第一行开始,按照行数添加到对应的数组,并且追加字符,然后一直遍历到最后一行对应的数组
            while (index < length && row < numRows) {
                char ch = str.charAt(index++);
                stringBuilders[row++].append(ch);
            }

            // 此时row是最后一行,所以我们需要回到倒数第二行,执行以下逻辑
            row = numRows - 2;

            // 从倒数第二行开始,按照行数添加到对应的数组,并且追加字符,然后一直遍历到第一行的对应的数组
            while (index < length && row >= 0) {
                char ch = str.charAt(index++);
                stringBuilders[row--].append(ch);
            }

            // 此时row是-1,所以我们需要回到第二行,执行以下逻辑
            row += 2;
        }
        // 创建一个新的StringBuilder,将每一行对应的StringBuilder数组对应的StringBuilder追加到这个对象
        StringBuilder resultSB = new StringBuilder();
        for (StringBuilder stringBuilder : stringBuilders) {
            resultSB.append(stringBuilder);
        }
        // 将这个StringBuilder转成字符串
        return resultSB.toString();
    }

}

Kotlin

/**
 * Created by TanJiaJun on 2021/6/14.
 * 6. Z字形变换(ZigZag Conversion)
 * 难度:中等
 *
 * @see <a href="https://leetcode-cn.com/problems/zigzag-conversion/">ZigZag Conversion</a>
 */
object ZigZagConversionKotlin {

    @JvmStatic
    fun main(args: Array<String>) {
        // 示例一
        print("示例一:")

        val firstStr = "PAYPALISHIRING"
        val firstNumRows = 3
        println(convert(firstStr, firstNumRows))

        print("\n")

        // 示例二
        print("示例二:")

        val secondStr = "PAYPALISHIRING"
        val secondNumRows = 4
        println(convert(secondStr, secondNumRows))

        print("\n")

        // 示例三
        print("示例三:")

        val thirdStr = "A"
        val thirdNumRows = 1
        println(convert(thirdStr, thirdNumRows))
    }

    /**
     * 时间复杂度:O(N),其中N是字符串的长度
     * 空间复杂度:O(N)
     *
     * @param str     字符串
     * @param numRows 行数
     * @return 结果
     */
    private fun convert(str: String, numRows: Int): String {
        if (numRows == 1) {
            // 如果只是一行的话,就直接返回该字符串
            return str
        }
        // 创建长度是行数的StringBuilder数组,并且每个元素都创建StringBuilder对象
        val stringBuilders = Array(numRows, init = { StringBuilder() })
        // 索引
        var index = 0
        // 行数
        var row = 0
        val length = str.length
        while (index < length) {
            // 从第一行开始,按照行数添加到对应的数组,并且追加字符,然后一直遍历到最后一行对应的数组
            while (index < length && row < numRows) {
                stringBuilders[row++].append(str[index++])
            }

            // 此时row是最后一行,所以我们需要回到倒数第二行,执行以下逻辑
            row = numRows - 2

            // 从倒数第二行开始,按照行数添加到对应的数组,并且追加字符,然后一直遍历到第一行的对应的数组
            while (index < length && row >= 0) {
                stringBuilders[row--].append(str[index++])
            }

            // 此时row是-1,所以我们需要回到第二行,执行以下逻辑
            row += 2
        }
        // 创建一个新的StringBuilder,将每一行对应的StringBuilder数组对应的StringBuilder追加到这个对象
        val resultSB = StringBuilder()
        stringBuilders.forEach { resultSB.append(it) }
        // 将这个StringBuilder转成字符串
        return resultSB.toString()
    }

}

时间复杂度:O(N),其中N是字符串的长度。

空间复杂度:O(N)。

题解

根据题目我们可以知道,字符串是按着反向N字形排列的,我们可以先创建一个长度是行数StringBuilder数组,然后定义一个row这样的指针来确定行数,为了方便理解,我举个例子,假设字符串PAYPALISHIRING,行数是3,我们从第一行开始,按照行数将字符添加到对应的数组,并且追加字符,然后一直遍历到最后一行对应的数组,此时这三个数组的情况如下所示:

  • 第一个数组:P
  • 第二个数组:A
  • 第三个数组:Y

此时的row的值是4,然后这个时候根据题目要求,我们的指针要回到倒数第二行,所以我们就要将row的值调整为行数减去2,也就是3-2等于1,然后开始继续遍历,此时这三个数组的情况如下所示:

  • 第一个数组:P
  • 第二个数组:A、P
  • 第三个数组:Y

然后我们的指针要从倒数第二行开始,按照行数添加到对应的数组,并且追加字符,然后一直遍历到第一行的对应的数组,此时这三个数组的情况如下所示:

  • 第一个数组:P、A
  • 第二个数组:A、P、L
  • 第三个数组:Y、I

此时row的值是-1,最后根据题目要求,我们的指针row要回到第二行,所以我们就要将row的值调整为自增2,也就是-1+2等于1,然后开始继续遍历,此时这三个数组的情况如下所示:

  • 第一个数组:P、A
  • 第二个数组:A、P、L、S
  • 第三个数组:Y、I

以此类推遍历下去,后面的逻辑就跟前面的逻辑一样了,这里就不再赘述了。

最后将这个StringBuilder数组遍历后追加到一个新的StringBuilder对象,然后转成字符串就可以得到最后的结果了。

我的GitHub:TanJiaJunBeyond

Android通用框架:Android通用框架

我的掘金:谭嘉俊

我的简书:谭嘉俊

我的CSDN:谭嘉俊

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容

  • 本系列通过Java和Kotlin这两种语言来解决力扣上面的算法题,由于本人算法菜鸟一枚,可能部分题目并不是最优题解...
    谭嘉俊阅读 277评论 0 1
  • 目录 1 左神部分集锦 2 Leetcode前150题 3 牛客网剑指offer 4 JavaG 5 题目中的...
    小小千千阅读 978评论 0 0
  • 《算法练习-文章汇总》[https://www.jianshu.com/p/fc7c0e8cc5cb] Day1:...
    一亩三分甜阅读 632评论 0 0
  • 表情是什么,我认为表情就是表现出来的情绪。表情可以传达很多信息。高兴了当然就笑了,难过就哭了。两者是相互影响密不可...
    Persistenc_6aea阅读 124,611评论 2 7
  • 16宿命:用概率思维提高你的胜算 以前的我是风险厌恶者,不喜欢去冒险,但是人生放弃了冒险,也就放弃了无数的可能。 ...
    yichen大刀阅读 6,042评论 0 4