LeetCode简单难度题解(一)

一、两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:
 给定 nums = [2, 7, 11, 15], target = 9
 因为 nums[0] + nums[1] = 2 + 7 = 9
 所以返回 [0, 1]

题解
方法接收参数为一个int数组 和一个目标值
创建一个Map :key:数组元素 value:数组下标
循环数组 ,判断map中是否有一个key等于 目标值减去当前循环数组元素
如果有 就结束方法 返回key对应的下标 和当前循环到的下标
如果循环走完 还没有匹配 返回 -1, -1

public static int[] twoSum2(int[] nums, int target){
    if (nums == null || nums.length < 2){
        return new int []{-1, -1};
    }
    int [] res = new int[]{-1, -1};
    HashMap<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < nums.length; i++){
        // 判断集合中有没有一个键 等于 目标值减去当前值
        if (map.containsKey(target - nums[i])){
            res[0] = map.get(target - nums[i]); // 和当前值对应的那个值的下标
            res[1] = i; // 当前值下标
            break;
        }
        map.put(nums[i],i); // 把当前值 和下标加入到  集合中
    }
    return res;
}

七、整数反转

给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
题解
定义一个res 为long型 为了防止反转后的越界
res每次*10 表示每次整体数字在最后加一位0
在加上 传过来的值%10表示把传过来的值最后一位加上去,再把传过来的值/10表示消除最后一位
当res超出int最大值 或小于int最小值的时候 返回0
否则把反转后的结果返回

public static int reverse2(int x) {
    long res = 0;
    while (x != 0) {
        res = res * 10 + x % 10; // 当前结果*10表示增加一位数  各位为0   x % 10 最传入值的各位
        x /= 10; // x值减少一位
        if (res > Integer.MAX_VALUE || res < Integer.MIN_VALUE) return 0;
    }
    return (int)res;
}

九、回文数

判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
题解
不断的把最后一位取出来附加到临时变量(temp)的个位
当temp大于传入参数(x)的时候 循环结束
返回结果 : temp == x || x == temp / 10 ;
temp / 10 表示如果传入参数为奇数 需要去除中位数在比较

 public static boolean isPalindrome(int x) {
        // 小于0的数 不是回文数
        // 最后一位为0的数不是回文数  如果为了使该数为回文数   只能是0
        if (x < 0 || (x % 10 == 0 && x != 0)) {
            return false;
        }
        int temp = 0;
        while (x > temp) {
            // 为了把数反过来    例:x=121 temp=0
            // 0*10 +121 % 10=1        1*10 + 12%10 = 12
            temp = temp * 10 + x % 10;
            // x=12  x=1
            x /= 10;
        }
        // 当数字长度为奇数时  可以通过temp / 10 去除中位数
        // 例: 12321  在进入while循环后  x = 12   temp = 123
        // 中位的数字不影响回文,所以可以将它去除
        return temp == x || x == temp / 10;
    }

如果理解不了 可以定一个零时变量(palind)存储传入的参数
再定义一个参数用来存储反转后的值(rev)
rev * 10 (增加一位) + x %10 取换入参数的最后一位
再把传入参数 / 10 去掉最后一位
返回 : 当palind == rev表示是回文数

  public static boolean isPalindrome2(int x) {
    if (x < 0 || x != 0 && x % 10 == 0) return false;
    int palind = x; // 先把 传进来的 x 值赋给一个新的变量
    int rev = 0; // 用于接收 翻转后的值
    while (x > 0) {  // 反转
        rev = rev * 10 + x % 10;
        x /= 10;
    }
    return palind == rev; // 判断反转后的值和 原来的值是否一致
}

十三、罗马数字转整数

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符 数值
 I 1
 V 5
 X 10
 L 50
 C 100
 D 500
 M 1000

例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
 通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
 
 给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。
题解
这里是有一个规律的,如果左边的数字小于右边的数字 = 右减左
首先定义一个方法,用于吧字符转成对应的数字
循环判断,如果循环到的这个数字 大于 前一个数 上面所说的规则成立
res += 当前值 - 2 * 前一个值
前两个是因为 前一个数再上一次循环的时候就已经加进去了,如果只是减一个那只能起到抵消的效果,没有起到减的效果

public static int romanToInt2(String s) {
    if (s == null || s.length() == 0) return 0;
    int res = toNumber(s.charAt(0));
    for (int i = 1; i < s.length(); i++){
        if (toNumber(s.charAt(i)) > toNumber(s.charAt(i - 1))){
            // res += toNumber(s.charAt(i))  表示的是把前面的数加上当前数
            // 如果后面不减两个前一个数的话   就只是把前一次数抵消掉    没有起到减的效果
            res += toNumber(s.charAt(i)) - 2 * toNumber(s.charAt(i - 1));
        }else {
            res += toNumber(s.charAt(i));
        }
    }
    return res;
}

public static int toNumber(char c){
    int res = 0;
    switch (c) {
        case 'I' : return 1;
        case 'V' : return 2;
        case 'X' : return 10;
        case 'L' : return 50;
        case 'C' : return 100;
        case 'D' : return 500;
        case 'M' : return 1000;
    }
    return res;
}

十四、最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 “”。
题解
定义一个临时变量(prefix)存放公共前缀
循环数组长度,内嵌套循环,条件:如果当前元素不是以prefix开头,就把prefix截取掉最后一位,再接着循环,找出他们两的公共前缀,其后每个元素同理接着操作
如果prefix为空了 表示没有公共的前缀 直接返回“”

public static String longestCommonPrefix(String[] strs) {
    if (strs.length == 0) {
        return "";
    }
    String prefix = strs[0];
    for (int i = 1; i < strs.length; i++){
        // 如果获取第一次出现的位置  为0的话 代表从开头开始都一样   但是第一个子串只有那么长  然后要取的是公共的最长 ,
        // 所以 如果第二个字符串比第一个长  最长公共串最多也只能是第一个字符串
        while (strs[i].indexOf(prefix) != 0) {// 如果两个字符串的 前缀  一样的话 表示 当前的prefix是他们的公共前缀
            // 更新相同的字符串前缀    每次把最后一个字符截取掉  在进行比较,
            prefix = prefix.substring(0, prefix.length()-1);
            if (prefix.isEmpty()) {// 如果为null了  表示他们没有公共前缀
                return "";
            }
        }
    }
    return prefix;
}

20、有效的括号

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。

有效字符串需满足:
 左括号必须用相同类型的右括号闭合。
 左括号必须以正确的顺序闭合。

注意空字符串可被认为是有效字符串。

题解
使用栈存储结构 先进后出
循环字符串
判断字符为(、[、{的时候 把对应的)、]、}存入栈
当循环到右括号的时候 从栈顶取出一个元素进行比较 如果不匹配 或栈已经为空 直接返回false
最后 如果栈中还剩余元素 也表示不匹配 返回false

public static boolean isValid2(String s) {
    if (s == null || s.length() == 0) return true;
    Stack<Character> stack = new Stack<>();
    for (Character ch : s.toCharArray()){ // 编译所有字符
        // 如果是左括号就添加进 栈
        if (ch == '('){
            stack.push(')');
        }else if(ch == '['){
            stack.push(']');
        }else if(ch == '{'){
            stack.push('}');
        }else{
            // 如果是右括号 就根栈顶元素比较   只要不匹配就直接返回false
            if (stack.isEmpty() || stack.pop() != ch) {
                return false;
            }
        }
    }
    // 如果全都匹配了  就没有剩余元素了   返回true
    return stack.isEmpty(); // 如果最后还有剩余的元素,返回false
}

21、合并两个有序列表

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
题解
初始化一个链表
在初始化一个链表 很第一个产生关联 用于迭代操作
循环判断 两个链表是否为空 只要其中一个为空就把剩下的值直接加到创建的链表中,如果不为空把小的值加到链表中,再更新链表中的值和用于迭代的链表

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    ListNode dummy = new ListNode(0); // 创建一个链表
    ListNode cur = dummy;
    while (l1 != null && l2 != null) { // 当其中一个链表的值没了就结束
        if (l1.val < l2.val) {
            cur.next = l1; // 把值给链表
            l1 = l1.next; // 刷新到下一个值
        }else{
            cur.next = l2;
            l2 = l2.next;
        }
        cur = cur.next;
    }
    // 哪个链表空了就把另一个链表之间接在后面
    if (l1 == null) {
        cur.next = l2;
    }else{
        cur.next = l1;
    }
    return dummy.next;
}

还一种递归解法 代码很简单 但是空间复杂度上升到了O(n)

public ListNode mergeTwoLists2(ListNode l1, ListNode l2) {
    if (l1 == null) return l2;
    if (l2 == null) return l1;
    if (l1.val < l2.val) {
        l1.next = mergeTwoLists2(l1.next,l2);
        return l1;
    }else{
        l2.next = mergeTwoLists2(l1,l2.next);
        return l2;
    }
}

26、删除排序数组中的重复项 返回数组长度

给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
题解
定义一个变量 用于存储长度(i)
从下标为1的元素开始迭代 每次跟前一个元素比较 不相等i++ 相同的情况下进入下一次循环,最后返回i + 1 因为循环从1开始 所以最后得把第一个数加回来

public int removeDuplicates(int[] nums) {
 if (nums.length == 0) return 0;
    int i = 0;
    for (int j = i + 1; j < nums.length; j++){
        if (nums[j] != nums[i]){   // 因为是一个排序数组,所以  每个不相同的数添加一个就好了  但是会忽略掉第一个
            nums[++i] = nums[j]; // 第一个数组元素不变  所以使用++i
        }
    }
    // 因为走循环的话  第一个数不会被加进去
    return i + 1;
}

27、移除元素 返回数组长度

给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
题解
这题就太简单了吧!!
定义一个临时变量 index 用来标识新数组下标位置
循环判断,吧不等于目标值的数加入数组下标为index的位置 index++ 最后返回index

public static int removeElement(int[] nums, int val) {
    if (nums == null || nums.length == 0) return 0;
    int index = 0;
    for (int i = 0; i < nums.length; i++){
        if (val != nums[i]){  // 把每个不等于val的值从新给赋值给数组
            nums[index++] = nums[i];// index用来标识   新添加元素的数组下标
        }
    }
    return index;
}

28、实现strStr()

实现 strStr() 函数。

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1
题解
哎 !!
不多说直接上代码
方法1:

public int strStr(String haystack, String needle) {
    if(needle == null || needle.equals("")) return 0;
    return haystack.indexOf(needle);
}

方法2:

public int strStr2(String haystack, String needle) {
    if(needle == null || needle.equals("")) return 0;
    
    for (int i = 0; i <= haystack.length() - needle.length(); i++){
        if (haystack.substring(i, i + needle.length()).equals(needle)) return i;
    }
    return -1;
}
  • 13
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值