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

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

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

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

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

项目的GitHub:Algorithm

整数反转(Reverse Integer)

难度:简单

链接:Reverse Integer

代码

Java

/**
 * Created by TanJiaJun on 2021/6/15.
 * 7. 整数反转(Reverse Integer)
 * 难度:简单
 *
 * @see <a href="https://leetcode-cn.com/problems/reverse-integer/">Reverse Integer</a>
 */
class ReverseInteger {

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

        int firstNumber = 123;
        System.out.println(reverse(firstNumber));

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

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

        int secondNumber = -123;
        System.out.println(reverse(secondNumber));

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

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

        int thirdNumber = 120;
        System.out.println(reverse(thirdNumber));

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

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

        int fourthNumber = 0;
        System.out.println(reverse(fourthNumber));

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

    /**
     * 时间复杂度:O(log|n|),其中n是整型x的位数
     * 空间复杂度:O(1)
     *
     * @param x 整型x
     * @return 结果
     */
    private static int reverse(int x) {
        int result = 0;
        while (x != 0) {
            // 得到最后一位,例如:123的3
            int digit = x % 10;
            if (result < -214748364 || (result == -214748364 && digit < -8)) {
                // 判断结果是否小于Integer.MIN_VALUE,也就是是否小于-2147483648
                return 0;
            }
            if (result > 214748364 || (result == 214748364 && digit > 7)) {
                // 判断结果是否大于Integer.MAX_VALUE,也就是是否大于2147483647
                return 0;
            }
            // 得到除了最后一位的前几位,例如:123的12
            x /= 10;
            result = result * 10 + digit;
        }
        return result;
    }

}

Kotlin

/**
 * Created by TanJiaJun on 2021/6/26.
 * 7. 整数反转(Reverse Integer)
 * 难度:简单
 *
 * @see <a href="https://leetcode-cn.com/problems/reverse-integer/">Reverse Integer</a>
 */
object ReverseIntegerKotlin {

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

        val firstNumber = 123
        println(reverse(firstNumber))

        print("\n")

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

        val secondNumber = -123
        println(reverse(secondNumber))

        print("\n")

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

        val thirdNumber = 120
        println(reverse(thirdNumber))

        print("\n")

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

        val fourthNumber = 0
        println(reverse(fourthNumber))

        print("\n")
    }

    /**
     * 时间复杂度:O(log|n|),其中n是整型x的位数
     * 空间复杂度:O(1)
     *
     * @param x 整型x
     * @return 结果
     */
    private fun reverse(x: Int): Int {
        var result = 0
        var number = x
        while (number != 0) {
            // 得到最后一位,例如:123的3
            val digit = number % 10
            if (result < -214748364 || (result == -214748364 && digit < -8)) {
                // 判断结果是否小于Integer.MIN_VALUE,也就是是否小于-2147483648
                return 0
            }
            if (result > 214748364 || (result == 214748364 && digit > 7)) {
                // 判断结果是否大于Integer.MAX_VALUE,也就是是否大于2147483647
                return 0
            }
            // 得到除了最后一位的前几位,例如:123的12
            number /= 10
            result = result * 10 + digit
        }
        return result
    }

}

时间复杂度:O(log|n|),其中n是整型x的位数。

空间复杂度:O(1)。

题解

大部分逻辑可以用数学表达式完成,举个例子:假设x123,袋盖步骤如下所示:

  1. 123 % 10 = 33就是最后一位,然后123 / 10得到12,结果就是3

  2. 12 % 10 = 22就是最后一位,然后12 / 10得到1,结果就是32

  3. 1 % 10 = 11就是最后一位,然后1 / 10得到0,结果就是321跳出循环

要注意的是,根据题义可知,如果反转后整数超过32位的有符号整数的范围[2^31, 2^31 - 1]就返回0并且环境不允许存储64位整数(有符号或者没有符号),也就是说我们不能使用long类型存储结果,所以我们需要对其进行判断,让结果在[2^31, 2^31 - 1]范围中,也就是[-2147483648, 2147483647]范围中,也就是如果result的值小于214748364或者大于214748364都不符合,如果result的值刚好是214748364呢?那就判断下digit的值,也就是最后一位是否小于8或者大于7

字符串转整数(atoi)(String to Integer(atoi))

难度:简单

链接:https://leetcode-cn.com/problems/string-to-integer-atoi/

代码

Java

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by TanJiaJun on 2021/6/18.
 * 8. 字符串转整数(atoi)(String to Integer(atoi))
 * 难度:简单
 *
 * @see <a href="https://leetcode-cn.com/problems/string-to-integer-atoi/">String to Integer(atoi)</a>
 */
class StringToInteger {

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

        String firstStr = "42";
        System.out.println(myAtoi(firstStr));

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

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

        String secondStr = "-42";
        System.out.println(myAtoi(secondStr));

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

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

        String thirdStr = "4193 with words";
        System.out.println(myAtoi(thirdStr));

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

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

        String fourthStr = "words and 987";
        System.out.println(myAtoi(fourthStr));

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

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

        String fifthStr = "-91283472332";
        System.out.println(myAtoi(fifthStr));
    }

    /**
     * 时间复杂度:O(N),其中N是字符串的长度
     * 空间复杂度:O(1)
     *
     * @param s 字符串
     * @return 结果
     */
    private static int myAtoi(String s) {
        // 去掉字符串前面和后面的空格
        s = s.trim();
        // ^[\+\-]?的意思是判断字符是否匹配+或者-,匹配零次或者一次
        // \d+的意思是判断字符是否匹配[0-9],匹配一次或者多次
        Pattern pattern = Pattern.compile("^[\\+\\-]?\\d+");
        Matcher matcher = pattern.matcher(s);
        boolean isInteger = matcher.find();
        int result = 0;
        if (isInteger) {
            try {
                result = Integer.parseInt(s.substring(matcher.start(), matcher.end()));
            } catch (NumberFormatException exception) {
                // 如果抛出NumberFormatException异常,证明小于整型的最小值,大于整型的最大值
                result = s.charAt(0) == '-' ? Integer.MIN_VALUE : Integer.MAX_VALUE;
            }
        }
        return result;
    }

}

Kotlin

import java.util.regex.Pattern

/**
 * Created by TanJiaJun on 2021/6/26.
 * 8. 字符串转整数(atoi)(String to Integer(atoi))
 * 难度:简单
 *
 * @see <a href="https://leetcode-cn.com/problems/string-to-integer-atoi/">String to Integer(atoi)</a>
 */
object StringToIntegerKotlin {

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

        val firstStr = "42"
        println(myAtoi(firstStr))

        print("\n")

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

        val secondStr = "-42"
        println(myAtoi(secondStr))

        print("\n")

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

        val thirdStr = "4193 with words"
        println(myAtoi(thirdStr))

        print("\n")

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

        val fourthStr = "words and 987"
        println(myAtoi(fourthStr))

        print("\n")

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

        val fifthStr = "-91283472332"
        println(myAtoi(fifthStr))
    }

    /**
     * 时间复杂度:O(N),其中N是字符串的长度
     * 空间复杂度:O(1)
     *
     * @param s 字符串
     * @return 结果
     */
    private fun myAtoi(s: String): Int {
        // 去掉字符串前面和后面的空格
        val str = s.trim()
        // ^[\+\-]?的意思是判断字符是否匹配+或者-,匹配零次或者一次
        // \d+的意思是判断字符是否匹配[0-9],匹配一次或者多次
        val pattern = Pattern.compile("^[\\+\\-]?\\d+")
        val matcher = pattern.matcher(str)
        val isInteger = matcher.find()
        var result = 0
        if (isInteger) {
            result = try {
                str.substring(startIndex = matcher.start(), endIndex = matcher.end()).toInt()
            } catch (exception: NumberFormatException) {
                // 如果抛出NumberFormatException异常,证明小于整型的最小值,大于整型的最大值
                if (str[0] == '-') Int.MIN_VALUE else Int.MAX_VALUE
            }
        }
        return result
    }
}

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

空间复杂度:O(1)。

题解

这道题我使用了正则表达式来解决,这里我解释下^[\+\-]?\d+这段正则表达式的含义:

  • ^[\\+\\-]?的意思是判断字符是否匹配+或者-,匹配零次或者一次
  • \\d+的意思是判断字符是否匹配[0-9],匹配一次或者多次

要注意的是,根据题义可知,结果要在[2^31, 2^31 - 1]范围内,所以如果抛出NumberFormatException异常的时候,需要将值设置为整型最小值Int.MIN_VALUE(2^31,2147483648)或者最大值Int.MAX_VALUE(2^31-1,2147483647)

回文数(Palindrome Number)

难度:简单

链接:https://leetcode-cn.com/problems/palindrome-number/

代码

Java

/**
 * Created by TanJiaJun on 2021/6/19.
 * 9. 回文数(Palindrome Number)
 * 难度:简单
 *
 * @see <a href="https://leetcode-cn.com/problems/palindrome-number/">Palindrome Number</a>
 */
class PalindromeNumber {

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

        int firstNumber = 121;
        System.out.println(isPalindrome(firstNumber));

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

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

        int secondNumber = -121;
        System.out.println(isPalindrome(secondNumber));

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

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

        int thirdNumber = 10;
        System.out.println(isPalindrome(thirdNumber));

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

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

        int fourthNumber = -101;
        System.out.println(isPalindrome(fourthNumber));
    }

    /**
     * 时间复杂度:O(N),其中N是整型x的位数
     * 空间复杂度:O(N),其中N是整型x的位数,因为要创建长度为位数的字符串
     *
     * @param x 整型x
     * @return 结果
     */
    private static boolean isPalindrome(int x) {
        // 将整型x转为字符串
        String str = String.valueOf(x);
        int length = str.length();
        // 只需要遍历该字符串长度一半就可以了
        for (int i = 0; i < length / 2; i++) {
            // 因为回文串的特性,我们可以用该字符和索引为length-i-1的字符比较是否相同就可以判断了
            if (str.charAt(i) != str.charAt(length - i - 1)) {
                // 只要有一个不相同,证明不是回文串
                return false;
            }
        }
        // 如果都相同,证明是回文串
        return true;
    }

}

Kotlin

/**
 * Created by TanJiaJun on 2021/6/26.
 * 9. 回文数(Palindrome Number)
 * 难度:简单
 *
 * @see <a href="https://leetcode-cn.com/problems/palindrome-number/">Palindrome Number</a>
 */
object PalindromeNumberKotlin {

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

        val firstNumber = 121
        println(isPalindrome(firstNumber))

        print("\n")

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

        val secondNumber = -121
        println(isPalindrome(secondNumber))

        print("\n")

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

        val thirdNumber = 10
        println(isPalindrome(thirdNumber))

        print("\n")

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

        val fourthNumber = -101
        println(isPalindrome(fourthNumber))
    }

    /**
     * 时间复杂度:O(N),其中N是整型x的位数
     * 空间复杂度:O(N),其中N是整型x的位数,因为要创建长度为位数的字符串
     *
     * @param x 整型x
     * @return 结果
     */
    private fun isPalindrome(x: Int): Boolean {
        // 将整型x转为字符串
        val str = x.toString()
        val length = str.length
        // 只需要遍历该字符串长度一半就可以了
        for (i in 0 until length / 2) {
            // 因为回文串的特性,我们可以用该字符和索引为length-i-1的字符比较是否相同就可以判断了
            if (str[i] != str[length - i - 1]) {
                // 只要有一个不相同,证明不是回文串
                return false
            }
        }
        // 如果都相同,证明是回文串
        return true
    }

}

时间复杂度:O(N),其中N是整型x的位数。

空间复杂度:O(N),其中N是整型x的位数,因为要创建长度为位数的字符串。

题解

由于回文串的特征是正读和反读都一样,例如:abba就是回文串abda就不是回文串了,所以我们只要找到某个字符,并且找到该字符索引length-i-1的字符,只需要遍历该字符串长度一半就可以判断该字符串是否为回文串,要注意的是,我这里先将整型x转为字符串,然后再执行相应的逻辑即可。

我的GitHub:TanJiaJunBeyond

Android通用框架:Android通用框架

我的掘金:谭嘉俊

我的简书:谭嘉俊

我的CSDN:谭嘉俊

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

推荐阅读更多精彩内容