• leetcode算法学习


    题目1:

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

    样例:

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

    解法1:

      一开始分析时将这道题分析的过于复杂,考虑了如果输出答案有多个该怎么办,但是根据题目的意思和测试样例,可以看出这道题的本意就是输出答案只有一个,并且不能重复使用同一个元素,所以最简单的办法就是暴力解决,两个for循环就可以搞定,但是这种解法最大的问题就在于复杂度为O(n2),效率很低,所以可以进行优化。优化的目的就是为了降低时间复杂度,而java很大的优势在于集合框架的使用,所以这里采用哈希表,将数组的值保存为key,将数组的索引保存为value,具体算法流程是:首先构造一个hashMap,然后遍历数组,如果target减去数组中的值在hashMap中存在对应的key,则将该key对应的value值和该数组的值的索引取出存在新的数组中返回;否则将该数组中的值和索引存到hashMap中。图解参考该牛人:

    两种解法如下:

    //暴力解法
        public static int[] twoSum(int[] nums, int target) {
            int[] index = new int[2];
            for (int i = 0; i < nums.length; i++) {
                for (int j = i; j < nums.length; j++) {
                    if ((nums[i] + nums[j]) == target && i != j) {
                        index[0] = i;
                        index[1] = j;
                    }
                }
            }
            return index;
        }
        //hashMap解法
        public static int[] twoSum1(int[] nums, int target) {
            Map<Integer, Integer> map = new HashMap<Integer, Integer>();
            for (int i = 0; i < nums.length; i++) {
                if (map.containsKey(target - nums[i])) {
                    return new int[] { map.get(target - nums[i]), i };
                }
                map.put(nums[i], i);
            }
            throw new IllegalArgumentException("No two sum solution.");
        }
    View Code

     题目2:

      给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。假设我们的环境只能存储得下32位的有符号整数,则其数值范围为 [−231,  231−1]。请根据这个假设,如果反转后整数溢出那么就返回 0。

    样例:

      输入: 123 输出: 321  输入: -123 输出: -321  输入: 120 输出: 21

    解法1:

    • 由简单到复杂入手,首先考虑如何对输入int类型数据反转,那就是先将int转化为String类型,定义一个StringBuffer类型变量,利用for循环逆序遍历使用String中的charAt()方法提取出每个字符,append到StringBuffer变量后即可。
    • 解决了反转问题,要考虑特殊情况如果是负数怎么办,那就在遍历前先对第一个字符进行判断,如果为‘-’号,先append该‘-’号。
    • 再考虑返回情况,因为要返回int类型,所以对StringBuffer类型使用toString()转换为String类型,再使用Integer的pareInt()方法转换为int类型。
    • 再考虑int数据类型溢出怎么办,若存在溢出情况,int会返回null类型,就无法进行格式转换,会报java.lang.NumberFormatException异常,所以捕获该异常按照要求返回0即可。

    解法2:

      上面分析的解法是最简单并且比较费时间的,那么另一种更高效的解法是对输入的每一位进行判断,看是否在反转后会发生溢出,使用ans作为保存的计算结果,pop作为下一位,判断思路如下:

    • 当考虑ans * 10 + pop > Integer.MAX_VALUE时:
      • 若出现 ans > Integer.MAX_VALUE / 10且还存在pop时,一定会发生溢出;
      • 若出现 ans == Integer.MAX_VALUE / 10 且 pop > 7(因为int最大值是 2,147,483,647(2^31 - 1)),一定会溢出。
    • 当考虑ans * 10 + pop < Integer.MIN_VALUE 时:
      • 若出现 ans < Integer.MIN_VALUE / 10且还存在pop时,一定会发生溢出;
      • 若出现 ans == Integer.MIN_VALUE / 10 且 pop < -8(因为int最小值是 -2,147,483,648(-2^31)),一定会溢出。

    package leetCodeTest;
    
    import java.util.Scanner;
    
    /*
     * 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
     * 输入: 123 输出: 321
     * 输入: -123 输出: -321
     * 输入: 120 输出: 21
     * 假设我们的环境只能存储得下 32 位的有符号整数,
     * 则其数值范围为 [−231,  231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
     * */
    public class test2 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner scanner = new Scanner(System.in);
            if (scanner.hasNextInt()) {
                int xInteger = scanner.nextInt();
                System.out.println(reverse1(xInteger));
            }
    
        }
        //转换字符解法
        public static int reverse(int x) {
            try {
                String xString = Integer.toString(x);
                StringBuffer xStringBuffer = new StringBuffer();
                if (xString.charAt(0) == '-') {
                    xStringBuffer.append(xString.charAt(0));
                    for (int i = xString.length() - 1; i > 0; i--) {
                        Character xCharacter = xString.charAt(i);
                        xStringBuffer.append(xCharacter);
                    }
    
                } else {
                    for (int i = xString.length() - 1; i >= 0; i--) {
                        Character xCharacter = xString.charAt(i);
                        xStringBuffer.append(xCharacter);
                    }
                }
                return Integer.parseInt(xStringBuffer.toString());
            } catch (NumberFormatException e) {
                // TODO: handle exception
                return 0;
            }
        }
        //判断每位是否溢出
        public static int reverse1(int x) {
            int ans = 0;
            while (x != 0) {
                int pop = x % 10;
                if (ans > Integer.MAX_VALUE / 10 || (ans == Integer.MAX_VALUE / 10 && pop > 7))
                    return 0;
                if (ans < Integer.MIN_VALUE / 10 || (ans == Integer.MIN_VALUE / 10 && pop < -8))
                    return 0;
                ans = ans * 10 + pop;
                x = x / 10;
            }
            return ans;
        }
    
    }
    View Code

     题目3:

      判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数(不将整数转为字符串) 。

    样例:

      输入: 121 输出: true  输入: -121 输出: false 解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。  输入: 10 输出: false 解释: 从右向左读, 为 01 。因此它不是一个回文数。

    解法1:

    • 如果是负数,直接返回false。
    • 否则每次从后往前按位取出再相加得到新值,新值与旧址比较若相等则返回true,不等则返回false。
    package leetCodeTest;
    
    import java.util.Scanner;
    
    /* 判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 
     * 输入: 121 输出: true
     * 输入: -121 输出: false 解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
     * 输入: 10 输出: false 解释: 从右向左读, 为 01 。因此它不是一个回文数。
     * 
     * 你能不将整数转为字符串来解决这个问题吗?
     * */
    public class test3 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner scanner = new Scanner(System.in);
            if (scanner.hasNextInt()) {
                System.out.println(isPalindrome(scanner.nextInt()));
            }
        }
    
        public static boolean isPalindrome(int x) {
            int temp = x;
            int x_reverse = 0;
            int pop = 0;
            if (x < 0) {
                return false;
            }
            while (x != 0) {
                pop = x % 10;
                x_reverse = x_reverse * 10 + pop;
                x = x / 10;
            }
            if (x_reverse == temp) {
                return true;
            } else {
                return false;
            }
        }
    
    }
    View Code

    题目4:

    解法1:

    • 首先构造一个hashMap存储7种字符和对应的数字
    • 对输入的字符串进行遍历,运用两个指针i和j,分别指向当前字符和下一个字符
    • 再保证指针j不越界的情况下,去判断指针i和指针j所指的元素是否为特殊的六种情况
    • 如果是则找到指针j所指的元素key对应的数字value按照规则减去相应的数字再相加,并i向后移动一位
    • 若不是则按照正常的哈希表寻找对应的value值后相加求和即可

    解法2:

    • 首先将所有可能存储到hashMap中,包括特殊的6中情况
    • 然后对字符串进行遍历,一种是1个字符,一种是2个字符,其中两个字符优先于1个字符
    • 先判断两个字符的组合在哈希表中是否存在,存在则将值取出加到结果中,并向后移2个字符。不存在则将判断当前1个字符是否存在,存在则将值取出加到结果中,并向后移 1 个字符
    • 最后返回结果
    package leetCodeTest;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Scanner;
    import java.util.Stack;
    
    /* 罗马数字转整数 */
    public class test4 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner scanner = new Scanner(System.in);
            if (scanner.hasNextLine()) {
                System.out.println(romanToInt(scanner.next()));
            }
    
        }
    
        public static int romanToInt(String s) {
            Map<Character, Integer> map = new HashMap<Character, Integer>();
            map.put('I', 1);
            map.put('V', 5);
            map.put('X', 10);
            map.put('L', 50);
            map.put('C', 100);
            map.put('D', 500);
            map.put('M', 1000);
    
            int sum = 0;
            for (int i = 0; i < s.length(); i++) {
                int j = i + 1;
                Character character1 = s.charAt(i);
    
                if (j < s.length()) {
                    Character character2 = s.charAt(j);
                    if (character1.equals('I') && (character2.equals('V') || character2.equals('X'))) {
                        sum = sum + map.get(character2) - 1;
                        i++;
                    } else if (character1.equals('X') && (character2.equals('L') || character2.equals('C'))) {
                        sum = sum + map.get(character2) - 10;
                        i++;
                    } else if (character1.equals('C') && (character2.equals('D') || character2.equals('M'))) {
                        sum = sum + map.get(character2) - 100;
                        i++;
                    } else {
                        sum = sum + map.get(character1);
                    }
                } else {
                    sum = sum + map.get(character1);
                }
            }
            return sum;
        }
    
        public static int romanToInt1(String s) {
            Map<String, Integer> map = new HashMap<String, Integer>();
            map.put("I", 1);
            map.put("V", 5);
            map.put("IV", 4);
            map.put("X", 10);
            map.put("IX", 9);
            map.put("L", 50);
            map.put("XL", 40);
            map.put("C", 100);
            map.put("XC", 90);
            map.put("D", 500);
            map.put("CD", 400);
            map.put("M", 1000);
            map.put("CM", 900);
    
            int sum = 0;
            for (int i = 0; i < s.length();) {
                if (i + 1 < s.length() && map.containsKey(s.substring(i, i + 2))) {
                    sum = sum + map.get(s.substring(i, i + 2));
                    i = i + 2;
                } else {
                    sum = sum + map.get(s.substring(i, i + 1));
                    i++;
                }
            }
            return sum;
        }
    
    }
    View Code

     题目5:

      编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。

    样例:

      输入: ["flower","flow","flight"] 输出: "fl"

      输入: ["dog","racecar","car"] 输出: "" 解释: 输入不存在公共前缀。

    解法1:

      一种水平扫描的方法,第一个字符串与第二个字符串得到最长前缀prefix,用prefix与第三个字符串找最长前缀更新prefix,以此类推,若prefix进行到空串就结束,否则遍历完最后一个prefix即为最长公共前缀。这里用到了String类里的indexOf方法,使用规则为string1.indexOf(string2),若string2为string1的子串,则返回最开始的索引,若不是子串则返回-1。

    解法2:

    • 首先取出第一串,用第一串的每个字符与剩下的每个串进行比较
    • 如果第一串的索引正好等于剩下串中某个串的长度,那么第一串就是该串的子字符串
    • 如果第一串i处的字符不等于剩下串中某个串的i处的字符,那么就从该处取字符串
    • 只要遇到第一串与剩下串不相同,就跳过该串

    解法3:

      利用分治的算法思想,将输入的字符串数组递归的划分为左右两个子数组,一直划分到子数组只有两个字符串时进行比较求最长前缀即可。

    package leetCodeTest;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.List;
    
    /*
     * 编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。
     * 输入: ["flower","flow","flight"] 输出: "fl"
     * 输入: ["dog","racecar","car"] 输出: "" 解释: 输入不存在公共前缀。*/
    public class test5 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            String[] strings = { "flower", "flow", "flight" };
            System.out.println(longestCommonPrefix2(strings));
        }
    
        // 解法1
        public static String longestCommonPrefix(String[] strs) {
            if (strs.length == 0) {
                return "";
            } else {
                String prefix = strs[0];
                for (int i = 1; i < strs.length; i++) {
                    while (strs[i].indexOf(prefix) != 0) {
                        prefix = prefix.substring(0, prefix.length() - 1);
                        if (prefix.isEmpty()) {
                            return "";
                        }
                    }
                }
                return prefix;
            }
        }
    
        // 解法2
        public static String longestCommonPrefix1(String[] strs) {
            if (strs.length == 0) {
                return "";
            } else {
                for (int i = 0; i < strs[0].length(); i++) {
                    char c = strs[0].charAt(i);
                    for (int j = 1; j < strs.length; j++) {
                        if (i == strs[j].length() || strs[j].charAt(i) != c) {
                            return strs[0].substring(0, i);
                        }
                    }
                }
                return strs[0];
            }
        }
    
        // 解法3
        public static String longestCommonPrefix2(String[] strs) {
            if (strs.length == 0) {
                return "";
            } else {
                return longestCommonPrefix2(strs, 0, strs.length - 1);
            }
        }
    
        public static String longestCommonPrefix2(String[] strs, int lo, int hi) {
            if (lo == hi) {
                return strs[lo];
            } else {
                int mid = (lo + hi) / 2;
                String leftString = longestCommonPrefix2(strs, lo, mid);
                String rightString = longestCommonPrefix2(strs, mid + 1, hi);
                return CommonPrefix2(leftString, rightString);
            }
        }
    
        public static String CommonPrefix2(String left, String right) {
            int min = Math.min(left.length(), right.length());
            for (int i = 0; i < min; i++) {
                if (left.charAt(i) != right.charAt(i)) {
                    return left.substring(0, i);
                }
            }
            return left.substring(0, min);
        }
    }
    View Code

     题目6:

      给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。

    样例:

      输入: "()"     输出: true  输入: "()[]{}"     输出: true  输入: "(]"     输出: false  输入: "([)]"     输出: false    输入: "{[]}"    输出: true

    分析:

    • 定义一个flag来判断是否进行了出栈操作
    • 遍历该字符串,使用栈来记忆遇到的左括号,包括’(‘ '[' '{',遇到则压栈
    • 每当遇到一个右括号时,从栈顶弹出元素并与当前字符串元素比较
    • flag为true的条件是从栈顶弹出的左括号正好与当前的右括号相对应,并且此时栈不为空
    • 最终返回flag
    package leetCodeTest;
    
    import java.util.EmptyStackException;
    import java.util.Stack;
    
    /*
     * 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
     * 有效字符串需满足:
     * 左括号必须用相同类型的右括号闭合。
     * 左括号必须以正确的顺序闭合。
    */
    public class test6 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            String string = "(])";
            System.out.println(isValid(string));
        }
    
        public static boolean isValid(String s) {
            Stack<Character> stack = new Stack<Character>();
            boolean flag = true;
            for (int i = 0; i < s.length(); i++) {
                if (s.charAt(i) == '(' || s.charAt(i) == '[' || s.charAt(i) == '{') {
                    stack.push(s.charAt(i));
                } else if (s.charAt(i) == ')') {
                    flag = flag && !stack.empty() && stack.pop() == '(';
                } else if (s.charAt(i) == ']') {
                    flag = flag && !stack.empty() && stack.pop() == '[';
                } else if (s.charAt(i) == '}') {
                    flag = flag && !stack.empty() && stack.pop() == '{';
                }
            }
            flag = flag && stack.empty();
            return flag;
        }
    }
    View Code

     题目7:

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

    样例:

      给定数组 nums = [1,1,2], 函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。

      给定 nums = [0,0,1,1,1,2,2,3,3,4],函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。

    分析:

    • 首先,题目告知给定一个已经排序好的数组,说明不是乱序
    • 设置两个指针i和j,i是慢指针,j是快指针
    • 当快指针指向的元素nums[j]等于慢指针指向的元素nums[i]时,慢指针停下,快指针继续向前遍历(跳过重复元素)
    • 当快指针指向的元素nums[j]不等于慢指针指向的元素nums[i]时,慢指针向前遍历,并将nums[j]复制到nums[i]中
    • 最终慢指针i遍历过的元素一定就是不相等的元素且一定是这些不相等元素的长度减1值
    package leetCodeTest;
    
    /* 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
     * 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
     * 给定数组 nums = [1,1,2], 函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。
     * 给定 nums = [0,0,1,1,1,2,2,3,3,4],函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
     * 不需要考虑数组中超出新长度后面的元素。*/
    public class test7 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            int[] nums = { 0, 0, 1, 1, 1, 2, 2, 3 };
            System.out.println(removeDuplicates(nums));
    
        }
    
        public static int removeDuplicates(int[] nums) {
            if (nums.length == 0) {
                return 0;
            }
            int i = 0;
            for (int j = 1; j < nums.length; j++) {
                if (nums[j] != nums[i]) {
                    i++;
                    nums[i] = nums[j];
                }
            }
            return i + 1;
        }
    
    }
    View Code

     题目8:

      给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

    样例:

      给定 nums = [3,2,2,3], val = 3,函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。

      给定 nums = [0,1,2,2,3,0,4,2], val = 2,函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。

    解法:

      参考上一道题,思路差不多,双指针法。

    package leetCodeTest;
    
    /*
     * 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。
     * 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
     * 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
     * 
     * 给定 nums = [3,2,2,3], val = 3,函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。
     * 给定 nums = [0,1,2,2,3,0,4,2], val = 2,函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
     * */
    public class test8 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            int[] nums = { 0, 1, 2, 2, 3, 0, 4, 2 };
            System.out.println(removeElement(nums, 2));
        }
    
        public static int removeElement(int[] nums, int val) {
            if (nums.length == 0) {
                return 0;
            }
            int i = 0;
            for (int j = 0; j < nums.length; j++) {
                if (nums[j] != val) {
                    nums[i] = nums[j];
                    i++;
                }
            }
            return i;
        }
    
    }
    View Code

    题目9:

      给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。你可以假设数组中无重复元素。

    样例:

      输入: [1,3,5,6], 5 输出: 2  输入: [1,3,5,6], 2 输出: 1

    解法:

    • 比较简单的解法,定义一个索引值index,遍历该数组,当遇到和目标值一样的值时,将该处的索引赋值给index,结束遍历
    • 当遇到第一个比目标值大的值时,将该处的索引赋值给index,这里就是目标值要插入的地方
    • 当遍历到最后一个元素时,表明前面的值都比目标值小,index赋值为数组的长度
    package leetCodeTest;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    /*
     * 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
     * 你可以假设数组中无重复元素。
     * 输入: [1,3,5,6], 5        输出: 2
     * 输入: [1,3,5,6], 2        输出: 1*/
    public class test10 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            int[] nums = { 1, 3, 5, 6};
            int target = 7;
            System.out.println(searchInsert(nums, target));
        }
    
        public static int searchInsert(int[] nums, int target) {
            int index = 0;
            for (int i = 0; i < nums.length; i++) {
                if (nums[i] == target) {
                    index = i;
                    break;
                } else if (nums[i] > target) {
                    index = i;
                    break;
                }else if (nums[i] < target && i == nums.length - 1) {
                    index = nums.length;
                }
            }
            return index;
        }
    
    }
    View Code

     题目10:

      报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:

      1. 1

      2. 11

      3. 21

      4. 1211

      5. 111221

      给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。注意:整数顺序将表示为一个字符串。

    分析:

      首先要理解这道题什么意思,当n=1时,是固定的为1;当n=2时,是对n=1的数的报数,即1个1(记作11);当n=3时,是对n=2的数的报数,即2个1(记作21);当n=4时,是对n=3的数的报数,即1个2和1个1(记作1211)以此类推。所以n其实就是对上一个数进行报数。

    解法:

      理解的题目的意思就要开始分析算法:

    • 当n=1时是一个最小的返回值,是最小规模,以后的n的计算都要返回到n=1考虑,所以可以联想到递归,每次递归得到的返回值就是为下一次进行铺垫
    • 对连续相同的数会进行计数,所以应该有一个计数器,当不连续时候归一重新开始计数
    package leetCodeTest;
    
    public class test11 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            System.out.println(countAndSay(4));
    
        }
    
        public static String countAndSay(int n) {
            StringBuffer stringBuffer = new StringBuffer();
            if (n == 1) {
                return "1";
            } else {
                int count = 1;
                String string = countAndSay(n - 1);
                for (int i = 0; i < string.length(); i++) {
                    if (i + 1 < string.length() && string.charAt(i) == string.charAt(i + 1)) {
                        count++;
                    } else {
                        stringBuffer.append(count).append(string.charAt(i));
                        count = 1;
                    }
                }
            }
            return stringBuffer.toString();
        }
    
    }
    View Code

    题目11:

      给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

    样例:

      输入: [-2,1,-3,4,-1,2,1,-5,4] 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6

    解法:

      采用动态规划的思想,将当前最大子连续和保存到为sum,结果为max

    • 若sum>0,表示sum对结果有增益效果,则 sum 保留并加上当前遍历数字
    • 若sum≤0,则说明 sum 对结果无增益效果,需要舍弃,则 sum 直接更新为当前遍历数字
    • 每次比较当前sum与当前max的最大值赋值到max中
    package leetCodeTest;
    /*
     * 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
     * 输入: [-2,1,-3,4,-1,2,1,-5,4]    输出: 6    解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
     * */
    import java.util.ArrayList;
    import java.util.List;
    
    public class test12 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            int[] nums = {4,-1,2,1};
            System.out.println(maxSubArray(nums));
        }
    
        public static int maxSubArray(int[] nums) {
            int max = nums[0];
            int sum = 0;
            for (int num : nums) {
                if (sum > 0) {
                    sum = sum + num;
                } else {
                    sum = num;
                }
                max = Math.max(max, sum);
            }
            return max;
        }
    }
    View Code

     题目12:

      给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度。如果不存在最后一个单词,请返回 0 。

    样例:

      输入: "Hello World" 输出: 5

    解法:

      这道题比较简单,使用trim()去掉头部和尾部的空格,然后使用split()按照空格划分,找到最后一个字符串计算长度即可。

    package leetCodeTest;
    
    /* 给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度。如果不存在最后一个单词,请返回 0 。
     * 输入: "Hello World"    输出: 5*/
    public class test13 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            System.out.println(lengthOfLastWord("Hello world "));
    
        }
    
        public static int lengthOfLastWord(String s) {
            String string = s.trim();
            if (string.length() == 0) {
                return 0;
            } else {
                String[] strings = string.split(" ");
                String lastString = strings[strings.length - 1];
                return lastString.length();
            }
            /*try {
                String[] strings = s.split(" ");
                String lastString = strings[strings.length - 1];
                return lastString.length();
            } catch (Exception e) {
                // TODO: handle exception
                return 0;
            }*/
    
        }
    
    }
    View Code

    题目13:

      给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。你可以假设除了整数 0 之外,这个整数不会以零开头。

    样例:

      输入: [1,2,3] 输出: [1,2,4] 解释: 输入数组表示数字 123。

      输入: [4,3,2,1] 输出: [4,3,2,2] 解释: 输入数组表示数字 4321。

    解法:

    • 对数组从后往前遍历
    • 加1的情况有两种,当为9时,加1之后变成10进1,当前为变为0;当不是9时,加1之后替换当前值
    • 可以进行判断,对加1的那一位对10取余数,如果余数为0,表示进位,如果余数不为0,表示没有进位,可直接return
    • 若遍历全部遍历完数组,表示都有进位,要在对数组长度加1且第一位为1
    package leetCodeTest;
    
    import java.util.function.IntPredicate;
    
    /* 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
     * 最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
     * 你可以假设除了整数 0 之外,这个整数不会以零开头。
     * 输入: [1,2,3]    输出: [1,2,4]    解释: 输入数组表示数字 123。
     * 输入: [4,3,2,1]    输出: [4,3,2,2]    解释: 输入数组表示数字 4321。
    */
    public class test14 {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            int[] digits = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
            System.out.println(plusOne(digits));
            // plusOne(digits);
        }
    
        public static int[] plusOne(int[] digits) {
            for (int i = digits.length - 1; i >= 0; i--) {
                digits[i]++;
                digits[i] = digits[i] % 10;
                if (digits[i] != 0)
                    return digits;
            }
            digits = new int[digits.length + 1];
            digits[0] = 1;
            return digits;
        }
    
    }
    View Code

  • 相关阅读:
    Python (一)Tkinter窗口组件:Label
    Python (八)Tkinter窗口组件:Scrollbar
    Python (四)Tkinter窗口组件:Radiobutton
    Python (五)Tkinter窗口组件:LabelFrame
    Python (三)Tkinter窗口组件:Checkbutton
    Scrapy安装及相关知识点概括
    Python (九)Tkinter窗口组件:Scale
    Python (六)Tkinter窗口组件:Entry
    电脑通过蓝牙适配器连接手机与蓝牙耳机之经验
    Noi2018 归途
  • 原文地址:https://www.cnblogs.com/yunkaiL/p/11342353.html
Copyright © 2020-2023  润新知