LeetCode经典算法题目一(字符串、数组、链表、栈、队列、哈希)

最近开始刷LeetCode,回顾了一下被我遗忘在角落里的数据结构和算法,包括java的基础语法。为了避免刷完了题又忘,所以在这里总结一下做过的题目,文中出现的所有代码均是用java编写,有不对的地方欢迎指正。
“业精于勤,荒于嬉;行成于思,毁于随。” 每天保持思考、学无止境、持续更新……
(以下内容均为本人总结内容,仅供学习参考)

LeetCode经典算法题目二(树、排序、查找、动态规划、回溯、贪心)

一、整数和字符串

1. 回文数

回文数是指:正序和倒序都是一样的数。
算法: 初始化y(倒序)为0,循环计算: y=y*10+rem(原数除以10的余数)

2. 整数反转输出

与回文数算法思想相同,但需要判断32位整数是否溢出,因为int类型占4个字节,取值范围为:-2147483648~2147483647,所以有可能出现原数为1999999999,如果反转就溢出了。
解决办法: 对结果变量定义为long类型,int 32位 long 64位,判断if((int)y == y)

3. 罗马数字转整数

用switch case语句将罗马数字与整数一一对应即可,需要考虑一下两个罗马数字组合的特殊情形,细节不再描述。
记一些有关字符串、数组和列表的常用方法:

1.int length();  //注意:字符串中是length()方法,数组中是length属性
2.char charAt(int index);  //取字符串中索引为index的字符元素
3.String indexOf(String str2);  //该方法在str1中检索str2,返回其在str1中第一次出现的位置索引,若找不到则返回-1。
4.String substring(int beginIndex, int endIndex);  //截取索引为 [beginIndex,endIndex) 的字符串
5.char[] toCharArray();  //把字符串转化为字符数组
6.System.arraycopy(原数组,原数组的开始位置,目标数组,目标数组的开始位置,拷贝的元素个数);  //(二/6)属于java.lang.System包中。
7.Arrays.sort(nums);  //(二/6)关于Arrays类中封装的排序方法(采用归并排序)。
//我在java api中整理了一些常用的,这里出现的数组类型都以int作为示例,当然其他的基本数组类型都是通用的。(见下图)
8.String replace(char oldChar, char newChar);  //(一/5)替换字符串中字符或者字符串,char也可以是String

在这里插入图片描述

4. 最长公共前缀

题目描述:
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。

算法一: 横向+纵向扫描,for循环嵌套。第一个for循环纵向扫描首个字符串的每一位字符,第二个for循环横向扫描数组中剩余字符串的对应位,若扫描到任意字符串与第一个字符串对应位的字符不同,则跳出两层for循环,用标记符号:break outter;实现。由于两个for循环,时间复杂度较高,性能较差。
将相同的字符添加到字符串str结尾。

StringBuilder sb = new StringBuilder(str);  //创建一个StringBuilder对象
sb.append( c); //再添加字符到尾部
str = sb.toString(); //转化成字符串

考虑数组越界: 因为输入的字符串数组的元素可能为0,即啥也不输入。所以要有判断if(strs.length==0)的语句(strs是字符串数组,String[] strs)
算法二: 横向扫描。锁定第一个字符串str,把它作为比较对象与剩余的字符串进行对比,每一次对比的是整个str ,若任意字符串不能检索到它,则让str长度减一,减去尾部字符,如此从后往前逐次去掉尾部不相同的字符,最终找到一个与剩余字符串相同的最长前缀。

String str = strs[0];
for(i=1;i<strs.length;i++){
   
   while(strs[i].indexOf(str) != 0){
     //由于要找的是公共前缀,因此这里需要判断第一次出现的索引是否为0
​      str = str.substring(0,str.length()-1);  // 截取减掉尾字符后剩余的字符串
   }  
}

5. x的平方根

如果使用for循环,在小于等于x的范围内逐个找值的话,虽然是一种解决办法,但是运行会超出时间限制。
计算平方根最好的办法是牛顿迭代法

class Solution {
   
    public int mySqrt(int x) {
   
        double x0,x1;
        x0=x;
        x1=(x0+x/x0)/2;
        while(Math.abs(x0-x1)>=1){
   
            x0=x1;
            x1=(x0+x/x0)/2;
        }
        return (int)x1;
    }
}

6. 实现strStr();(★)

我没自己写算法实现,直接用的java封装好的方法str1.indexOf(str2)在str1中检索str2,个人觉得没有太大必要费工夫来写这个,因为indexOf()太好用且常用了。

7. 最后一个单词的长度

算法: 将原字符串倒序循环依次取每个字符,遇到不为空格的字符则长度计数m加1;遇到空格字符但是m等于0(m初始化为0),则继续循环;遇到空格字符且m大于0,则退出while循环,返回m的值。

8. 反转字符串(★★)

算法: 双指针。将left和right指向的元素互换,不断往中间走。
(我用的也是首尾元素互换的思想,但是运行要比双指针慢一点。可能因为循环条件里面我写的i<len/2每次循环都要计算这个所以慢一点吧。但原理是一样的)

class Solution {
   
    public void reverseString(char[] s) {
   
        int len=s.length;
        int left=0,right=len-1;
        char tem;
        while(left<right){
     //当左右指针走到中间就结束(奇偶都成立)
            tem = s[left];
            s[left] = s[right];
            s[right] = tem;
            left++;
            right--;
        }
    }
}

9. 替换空格(★)

题目描述:请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

方法一: 使用String类的方法:replace(String old,String new);

class Solution {
   
    public String replaceSpace(String s) {
   
        return s.replace(" ","%20");
    }
}

方法二: 使用StringBuilder在尾部逐个添加字符。

class Solution {
   
    public String replaceSpace(String s) {
   
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<s.length();i++){
   
            if(s.charAt(i) == ' ')
                sb.append("%20");
            else
                sb.append(s.charAt(i));
        }
        return sb.toString();
    }
}

10. 字符串转换整数 (atoi)(★)

题目描述:请你来实现一个 atoi 函数,使其能将字符串转换成整数。
首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下:
1、如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。
2、假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。
3、该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。
*注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。在任何情况下,若函数不能进行有效的转换时,请返回 0 。
*提示:
本题中的空白字符只包括空格字符 ’ ’ 。
假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。

调用Character类的静态方法static boolean isDigit(char c)可以判断当前字符是否为数字,如果为数字,再使用:int digit = c - '0'; 来实现字符转换为数字,从而可以使用:num = num * 10 + digit; 来实现将字符串转换为整数
int的最大值:Integer.MAX_VALUE
int的最小值:Integer.MIN_VALUE

class Solution {
   
    public int myAtoi(String str) {
   
        int len = str.length();
        int index=0;
        while(index<len){
     //先处理前面的空格字符
            if(str.charAt(index)!=' ')
                break;
            index++;
        }
        boolean negative = false;  //负号标识符
        if(index<len && str.charAt(index)=='-'){
     //负数
            negative = true;
            index++;
        }
        else if(index<len && str.charAt(index)=='+'){
     //正数
            index++;
        }
        int num=0;
        while(index<len && Character.isDigit(str.charAt(index))){
     //若当前字符为数字
            int digit = str.charAt(index) - '0';  //字符转数字
            if(num > (Integer.MAX_VALUE-digit)/10){
     //若加上这个数字后超出int的范围
                return negative?Integer.MIN_VALUE:Integer.MAX_VALUE;  //返回最大或最小
            }
            num = num * 10 + digit;//字符串转整数
            index++;
        }
        return negative?-num:num;
    }
}

11. 用 Rand7() 实现 Rand10()(★)

题目描述:已有方法 rand7 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10 生成 1 到 10 范围内的均匀随机整数。
不要使用系统的 Math.random() 方法。

/**
 * The rand7() API is already defined in the parent class SolBase.
 * public int rand7();
 * @return a random integer in the range 1 to 7
 */
class Solution extends SolBase {
   
    public int rand10() {
   
        int num = (rand7()-1) * 7 + rand7();
        while(num > 40){
   
            num = (rand7()-1) * 7 + rand7();
        }
        return num%10 + 1;
    }
}

二、数组

1. 删除排序数组中的重复项(★★)

题目描述:给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

算法: 利用双指针:慢指针i和快指针j。i指向的元素才是最终的新数组的元素。

时间复杂度O(n). 假设数组的长度是 n,那么 i 和 j 分别最多遍历 n 步。
空间复杂度:O(1)

class Solution {
   
    public int removeDuplicates(int[] nums) {
   
        if(nums.length==0)
            return 0;
        int i=0;
        for(int j=1;j<nums.length;j++){
   
            if(nums[i]!=nums[j])  //若num[i]!=nums[j],则把j指向的值赋给i的下一个元素
                nums[++i]=nums[j];
        }
        return i+1;
    }
}

注意:for(j;j<nums.length;j++) 写法错误!java语法在for循环中必须先对循环变量赋值,对j初始化:int j=

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞行的小猪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值