数据结构与算法

LeetCode题解笔记

菠萝猫 · 8月31日 · 2020年 241次已读

1.TwoSum

```
//给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
//
// 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
// 示例:
// 给定 nums = [2, 7, 11, 15], target = 9
//
//因为 nums[0] + nums[1] = 2 + 7 = 9
//所以返回 [0, 1]
//
// Related Topics 数组 哈希表

import java.util.HashMap;

/**
 * @Description:两数之和
 * @Author: liuzhi
 * @Date: 2020/6/3 11:09
 **/
public class TwoSum {
    public static void main(String[] args) {
        Solution1 solution = new Solution1();
        int[] nums = {2, 7, 11, 15};
        int[] ints = solution.twoSum(nums, 9);
        System.out.println(ints[0]+" "+ints[1]);
    }
}
class Solution1 {
    public int[] twoSum(int[] nums, int target) {
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int num = target - nums[i];
            if (map.containsKey(num)){
                return new int[]{map.get(num),i};
            }
            map.put(nums[i],i);
        }
        throw new RuntimeException("no answer!");
    }
}
```

2.AddTwoNumbers

```java
//给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。 
//
// 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。 
//
// 您可以假设除了数字 0 之外,这两个数都不会以 0 开头。 
//
// 示例: 
//
// 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
//输出:7 -> 0 -> 8
//原因:342 + 465 = 807
// 
// Related Topics 链表 数学

/**
 * @Description:两数相加
 * @Author: liuzhi
 * @Date: 2020/6/2 17:25
 **/
public class AddTwoNumbers {
    public static void main(String[] args) {
        Solution solution = new AddTwoNumbers().new Solution();
        ListNode listNode1 = new ListNode(9);
        ListNode listNode2 = new ListNode(1);
        listNode1.add(2);
        ListNode listNode = solution.addTwoNumbers(listNode1, listNode2);
        if (listNode!=null){
            listNode.print();
        }
    }

    class Solution {
        public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
            int carry=0;
            ListNode lResult = new ListNode(0);//初始值为0的节点
            ListNode newNode = lResult;
            while (l1!=null||l2!=null){
                int n1 = 0,n2 = 0;
                if (l1!=null){
                     n1 = l1.val;
                     l1=l1.next;
                }
                if (l2!=null){
                    n2 = l2.val;
                    l2=l2.next;
                }
                int temp = n1 + n2 + carry;
                carry = temp/10;//进位值
                temp = temp %10;//有效位值
                newNode.next = new ListNode(temp);
                newNode = newNode.next;
            }
            if (carry>0){
                newNode.next = new ListNode(carry);//最后一位是否有进位
            }
            return  lResult.next;
        }
    }
    static class ListNode{
        int val;   //数值 data
        ListNode next; // 结点 node
        ListNode() {   //可以定义一个有参构造方法,也可以定义一个无参构造方法
        }
        ListNode(int x){   //可以定义一个有参构造方法,也可以定义一个无参构造方法
            val = x;
        }
        // 添加新的结点
        public void add(int newval) {
            ListNode newNode = new ListNode(newval);
            if(this.next == null) {
                this.next = newNode;
            } else {
                this.next.add(newval);
            }
        }
        // 正序打印链表
        public void print() {
            System.out.print(this.val);
            if(this.next != null)
            {
                System.out.print("-->");
                this.next.print();
            }
        }

    }
}
```

3.LongestSubstringWithoutRepeatingCharacters

```java
//给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。 
//
// 示例 1: 
// 输入: "abcabcbb"
//输出: 3 
//解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
// 
// 示例 2: 
// 输入: "bbbbb"
//输出: 1
//解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
// 
// 示例 3: 
// 输入: "pwwkew"
//输出: 3
//解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
//     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
// 
// Related Topics 哈希表 双指针 字符串 Sliding Window

import java.util.HashMap;

/**
 * @Description:无重复字符的最长子串
 * @Author: liuzhi
 * @Date: 2020/6/3 11:04
 **/
public class LongestSubstringWithoutRepeatingCharacters {
    public static void main(String[] args) {
        Solution solution = new Solution();
        System.out.println(solution.lengthOfLongestSubstring("abcabcd"));
    }
}

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int maxLength = 0;
        int start = 0;
        for(int i = 0; i < s.length(); i++){
            start = start + s.substring(start, i).indexOf(s.charAt(i)) + 1;
            //substring() 方法返回字符串的子字符串。
            //int indexOf(String str): 返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1
            maxLength = Math.max(maxLength, i - start + 1);
        }
        return maxLength;
    }
}
```

5.LongestPalindromicSubstring

```java
//给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 
//
// 示例 1: 
// 输入: "babad"
//输出: "bab"
//注意: "aba" 也是一个有效答案。
// 
// 示例 2: 
// 输入: "cbbd"
//输出: "bb"
// Related Topics 字符串 动态规划

/**
 * @Description:最长回文子串(暴力破解法)
 * @Author: liuzhi
 * @Date: 2020/6/6 20:25
 **/
public class LongestPalindromicSubstring {
    public static void main(String[] args) {
        String s = "ac";
        System.out.println(new Solution4().longestPalindrome(s));
    }

}
class Solution4 {
    public String longestPalindrome(String s) {
        int len = s.length();
        if (len<2){
            return s;
        }
        int maxLen = 1;
        String res = s.substring(0,1);

        for (int i = 0; i < len-1; i++) {
            for (int j = i+1; j < len; j++) {
                if (j-i+1>maxLen&&valid(s,i,j)){
                    maxLen = j-i+1;
                    res = s.substring(i,j+1);
                }
            }
        }
        return res;
    }
    private boolean valid(String s, int left, int right){
        while (left<right){
            if (s.charAt(left)!=s.charAt(right)){
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
}

/**
 * @Description:最长回文子串
 * @Author: liuzhi
 * @Date: 2020/6/6 21:00
 **/
public class LongestPalindromicSubstring2 {
    public static void main(String[] args) {
        String s = "ac";
        System.out.println(new Solution5().longestPalindrome(s));
    }
}

class Solution5 {
    private int lo = 0,maxLen = 0;
    public String longestPalindrome(String s) {
        int len = s.length();
        if (len<2){
            return s;
        }
        for (int i = 0; i < len-1; i++) {
            extendPalindrome(s,i,i);
            extendPalindrome(s,i,i+1);
        }
        return s.substring(lo,lo+maxLen);
    }

    private void extendPalindrome(String s,int j,int k){
        while (j>=0&&k<s.length()&&s.charAt(j)==s.charAt(k)){
            j--;
            k++;
        }
        if (maxLen<k-j-1){
            lo = j+1;
            maxLen = k-j-1;
        }
    }

}
```

6.ZigzagConversion

```java
//将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。 
//
// 比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下: 
// L   C   I   R
//E T O E S I I G
//E   D   H   N
// 
// 之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。 
//
// 请你实现这个将字符串进行指定行数变换的函数: 
//
// string convert(string s, int numRows); 
//
// 示例 1: 
// 输入: s = "LEETCODEISHIRING", numRows = 3
//输出: "LCIRETOESIIGEDHN"
// 
// 示例 2:
// 输入: s = "LEETCODEISHIRING", numRows = 4
//输出: "LDREOEIIECIHNTSG"
//解释:
//L     D     R
//E   O E   I I
//E C   I H   N
//T     S     G 
// Related Topics 字符串

/**
 * @Description:
 * @Author: liuzhi
 * @Date: 2020/6/7 11:00
 **/
public class ZigzagConversion {
    public static void main(String[] args) {
        Solution solution = new ZigzagConversion().new Solution();
        System.out.println(solution.convert("LEETCODEISHIRING", 4));
    }

    //leetcode submit region begin(Prohibit modification and deletion)
    class Solution {
        public String convert(String s, int numRows) {
            char[] chars = s.toCharArray();
            int len = chars.length;
            StringBuffer[] sb = new StringBuffer[numRows];
            for (int i = 0; i < sb.length; i++) {
                sb[i]=new StringBuffer();
            }
            int i=0;
            while (i<len){
                for (int j = 0; j < numRows&&i<len; j++) {
                    sb[j].append(chars[i++]);
                }
                for (int j = numRows-2; j >= 1&&i<len; j--) {
                    sb[j].append(chars[i++]);
                }
            }
            for (int j = 1; j < sb.length; j++) {
                sb[0].append(sb[j]);
            }
            return sb[0].toString();
        }
    }
}
```

7.ReverseInteger

```java
//给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。 
// 示例 1:
// 输入: 123
//输出: 321
// 
// 示例 2:
// 输入: -123
//输出: -321
// 
// 示例 3: 
// 输入: 120
//输出: 21
// 
// 注意: 
// 假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。
// 请根据这个假设,如果反转后整数溢出那么就返回 0。
// Related Topics 数学

/**
 * @Description:整数反转
 * @Author: liuzhi
 * @Date: 2020/6/4 13:34
 **/
public class ReverseInteger {
    public static void main(String[] args) {
        System.out.println(new Solution3().reverse(-123));
    }
}

class Solution3 {
    public int reverse(int x) {
        int result = 0;
        while (x != 0) {
            int tail = x % 10; //获取个位数
            int newResult = result * 10 + tail; //反转后的数
            if ((newResult - tail) / 10 != result) { //判断反转后整数是否溢出
                return 0;
            }
            result = newResult;
            x = x / 10; //获取前几位数
        }
        return result;
    }
}
```

8.StringToIntegerAtoi

```java
//请你来实现一个 atoi 函数,使其能将字符串转换成整数。 
//
// 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下: 
// 如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。 
// 假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。 
// 该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。
// 注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。 
//
// 在任何情况下,若函数不能进行有效的转换时,请返回 0 。 
//
// 提示: 
// 本题中的空白字符只包括空格字符 ' ' 。 
// 假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 INT_MAX (231
// − 1) 或 INT_MIN (−231) 。 
//
// 示例 1: 
// 输入: "42"
//输出: 42
// 
// 示例 2: 
// 输入: "   -42"
//输出: -42
//解释: 第一个非空白字符为 '-', 它是一个负号。
//     我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。
// 
// 示例 3: 
// 输入: "4193 with words"
//输出: 4193
//解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。
// 
// 示例 4: 
// 输入: "words and 987"
//输出: 0
//解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
//     因此无法执行有效的转换。 
//
// 示例 5: 
// 输入: "-91283472332"
//输出: -2147483648
//解释: 数字 "-91283472332" 超过 32 位有符号整数范围。 
//     因此返回 INT_MIN (−231) 。
// 
// Related Topics 数学 字符串

/**
 * @Description:字符串转换为整数
 * @Author: liuzhi
 * @Date: 2020/6/10 9:56
 **/
public class StringToIntegerAtoi {
    public static void main(String[] args) {
        Solution solution = new StringToIntegerAtoi().new Solution();
        System.out.println(solution.myAtoi("42"));
    }

    class Solution {
        public int myAtoi(String str) {
            String str2 = str.trim();
            long sum =0;
            int sign = 1,start=0;
            if (str2.length()==0){
                return 0;
            }
            if (str2.charAt(0)=='+'){
                sign = 1;
                start++;
            }
            if (str2.charAt(0)=='-'){
                sign = -1;
                start++;
            }
            for (int i = start; i < str2.length() ; i++) {

                if (!Character.isDigit(str2.charAt(i))){
                    return (int)sum*sign;
                }
                sum = sum * 10 + (str2.charAt(i)-'0');
                if (sign==1&&sum>Integer.MAX_VALUE){
                    return Integer.MAX_VALUE;
                }
                if (sign==-1&&(-1)*sum<Integer.MIN_VALUE){
                    return Integer.MIN_VALUE;
                }
            }

            return (int)sum*sign;
        }
    }
}
```

9.PalindromeNumber

```java
//判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 
//
// 示例 1: 
// 输入: 121
//输出: true
// 
// 示例 2:
// 输入: -121
//输出: false
//解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
// 
// 示例 3: 
// 输入: 10
//输出: false
//解释: 从右向左读, 为 01 。因此它不是一个回文数。
// 
// 进阶: 
// 你能不将整数转为字符串来解决这个问题吗? 
// Related Topics 数学

/**
 * @Description:回文数
 * @Author: liuzhi
 * @Date: 2020/6/10 10:37
 **/
public class PalindromeNumber {
    public static void main(String[] args) {
        Solution solution = new PalindromeNumber().new Solution();
        System.out.println(solution.isPalindrome(-121));
    }

    class Solution {
        public boolean isPalindrome(int x) {
            String s = String.valueOf(x);
            int length = s.length();
            int sum=0;
            for (int i = length-1; i>=0; i--) {
                int i1 = s.charAt(i) - '0';
                sum = sum * 10 + i1;
            }
            if (sum==x){
                return true;
            }else {
                return false;
            }
        }
    }
}
```


版权声明:本站采用 “知识共享署名 – 非商业性使用 – 相同方式共享 4.0 中国大陆许可协议” 进行许可,您可以转载本站文章,转载时请以超链接形式标明文章原始出处,Thanks.


1 条回应
  1. 马老师的大皮燕子2020-10-13 · 10:20
    Microsoft Edge Microsoft Edge Windows Windows

    感谢马老师的大皮燕子送出的飞机✈