LeetCode解题记录(一)

1、两数之和

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

示例 1:输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:输入:nums = [3,3], target = 6
输出:[0,1]

思路1嵌套遍历a、b两个数,找到相加等于target的,并且a、b的位置不能相同

    /**
     * 1. 两数之和
     *
     * @param nums
     * @param target
     * @return
     */
    public int[] twoSum(int[] nums, int target) {
        int[] resultArr;
        for (int i = 0; i < nums.length; i++) {
            int n1 = nums[i];
            for (int j = 0; j < nums.length; j++) {
                int n2 = nums[j];
                //两个值相加等于target,且两个值的下标不能相同
                if (n1 + n2 == target && i != j) {
                    resultArr = new int[]{i, j};
                    return resultArr;
                }
            }
        }
        return new int[]{};
    }

    public int[] twoSum2(int[] nums, int target) {
        //用来记录脚标和脚标对应的值
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int n = target - nums[i];
            //包含说明找到了能加出target的组合
            if (map.containsKey(n)) {
                return new int[]{map.get(n), i};
            }
            //找不到的话,把脚标和脚标对应的值记录下来
            map.put(nums[i], i);
        }
        return new int[]{};
    }

2、无重复字符的最长子串

题目描述:给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

思路:遍历字符串...

public int lengthOfLongestSubstring(String s) {
        int i = 0;
        int maxLen = 0;
        while (i < s.length()) {
            StringBuilder a = new StringBuilder();
            for (int j = i; j < s.length(); j++) {
                if (!a.toString().contains(s.charAt(j) + "")) {
                    a.append(s.charAt(j));
                } else {
                    break;
                }
            }
            if (maxLen < a.length()) {
                maxLen = a.length();

            }
            i++;
        }
        return maxLen;
    }

3、最长回文字符

给你一个字符串 s,找到 s 中最长的回文子串。如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

示例 1:输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。


示例 2:输入:s = "cbbd"
输出:"bb"

思路:回文的特点是对称,如果字符串的长度为奇数,从最中间一个点开始(自己对称),左右两边应该都是对称的(值相同)如:aba;如果字符串的长度为偶数,则从中间两个点开始,左右都是对称的,如abba。

根据回文的这个特点,我们可以把字符串的每一位都当作中心点,依次以回文串是奇数或是偶数的情况进行比对,找出符合条件的回文串并进行长度的比较。

/**
     * 最长回文子串
     * 回文的特点:从中间位置开始,两边都是对称的
     * 把每一位都当作中心扩散点,从中间向两边寻找,发现左右不对称,说明不(再)是回文
     *
     * @param s
     * @return
     */
    public String longestPalindrome(String s) {
        if (s == null || s.length() == 0) {
            return "";
        }
        String result = "";
        for (int i = 0; i < s.length(); i++) {
            //字符串中的回文是奇数,以当前的索引位置作为起点,左右扩散
            String oddRes = getPalindrome(s, i, i);
            //字符串中的回文是偶数,以当前的索引位置和它后一个位置作为起点,左右扩散
            String evenRes = getPalindrome(s, i, i + 1);
            //比较长度
            result = result.length() < oddRes.length() ? oddRes : result;
            result = result.length() < evenRes.length() ? evenRes : result;

        }
        return result;
    }

    public String getPalindrome(String s, int toLeft, int toRight) {
        while (toLeft >= 0 && toRight < s.length()) {
            //左边等于右边,说明对称
            if (s.charAt(toLeft) == s.charAt(toRight)) {
                toLeft--;
                toRight++;
            } else {
                break;
            }
        }
        //这里跳出的条件是在最后一次满足条件后又做了一次--++,因此跳出时的left和right已经都是不符合条件的了;
        // 结合subString的特点是左边包括,右边不包括;因此左边+1,右边不变
        return s.substring(toLeft + 1, toRight);
    }

4、N字形变换

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:

P   A   H   N
A P L S I I G
Y   I   R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。

示例 1:输入:s = "PAYPALISHIRING", numRows = 3
输出:"PAHNAPLSIIGYIR"


示例 2:输入:s = "PAYPALISHIRING", numRows = 4
输出:"PINALSIGYAHRPI"
解释:
P     I    N
A   L S  I G
Y A   H R
P     I


示例 3:输入:s = "A", numRows = 1
输出:"A"

思路:按行找规律,找到规律顺序读出即可
1、每行的第一个元素的索引(位置)等于行数对应的索引i
2、第一行和最后一行元素之间的位置相差2*总行数-2
3、其他行位置相差 以 2*总行数-2-2*i 和 2*i 交替
4、如果行数为1,返回原字符串

 public String convert(String s, int numRows) {
        StringBuilder newS = new StringBuilder();
        int step = 2 * numRows - 2;
        if (step == 0) {
            return s;
        }
        int sIndex = 0;
        boolean flag = true;
        for (int i = 0; i < numRows; i++) {
            //每行打头的索引位置等于所在行数目
            sIndex = i;
            flag = true;
            while (sIndex < s.length()) {
                newS.append(s.charAt(sIndex));
                if (i == 0 || i == numRows - 1) {
                    sIndex += step;
                } else {
                    if (flag) {
                        sIndex += (step - 2 * i);
                    } else {
                        sIndex += 2 * i;
                    }
                    flag = !flag;
                }
            }
        }
        return newS.toString();
    }

5、整数反转

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [−231,  231 − 1] ,就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)。

示例 1:输入:x = 123
输出:321


示例 2:输入:x = -123
输出:-321


示例 3:输入:x = 120
输出:21


示例 4:输入:x = 0
输出:0

思路:主要需解决整数末尾0的问题,需要把末尾的连续0去掉,使用求余+除法的方式循环把末尾的连续0去掉
注意点1:0的处理
注意点2:边界处理

public int reverse(int x) {
        while (x != 0) {
            if (x % 10 == 0) {
                x = x / 10;
            } else {
                break;
            }
        }
        String xString = String.valueOf(x);
        StringBuilder resStr = new StringBuilder(xString);
        resStr.reverse();
        String res = resStr.toString();
        if (x < 0) {
            res = resStr.substring(0, resStr.length() - 1);
            res = "-" + res;
        }
        try {
            return Integer.parseInt(res);
        } catch (Exception e) {
            return 0;
        }
    }

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值