zoukankan      html  css  js  c++  java
  • 算法练习 —— LeetCode 1-20题

    一、两数之和

    1.1 题目描述

    给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。

    你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。

    示例:

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

    1.2 解题思路

    有目标数,又限制是两个数之和,所以知道若一个数为nums[i],则另一个数为target-nums[i]。

    借助Map的数据结构,key为nums[i],value为i。

    则答案应符合i、map.get(target-nums[i])。

    1.3 解法

    时间复杂度为(O(n))
    空间复杂度为(O(n))

    
    public class Solution {
    
        public static int[] twoSum(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])){
                    int[] result = new int[2];
                    result[0] = map.get(target-nums[i]);
                    result[1] = i;
                    return result;
                }else{
                    map.put(nums[i],i);
                }
            }
    
            return null;
        }
    
    }
    
    

    代码进一步简化

    class Solution {
        public int[] twoSum(int[] nums, int target) {
            Map<Integer,Integer> map = new HashMap<>();
            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);
            }
            return null;
        }
    }
    

    二、两数相加

    2.1 题目描述

    给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

    如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
    您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

    示例:
    输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
    输出:7 -> 0 -> 8
    原因:342 + 465 = 807

    2.2 解题思路

    思路是使用链表,定义变量sum来计算两条链表的对应节点的值,对sum%10作为新节点的值,sum/10判断是否进位。两条链表对应节点相加,若最后sum/10等于1,则新创建一个节点,放在尾部。

    2.3 解法

    时间复杂度为(O(n))
    空间复杂度为(O(n))

    
    class Solution {
        public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
            ListNode dummy = new ListNode(0);
            ListNode cur = dummy;
            ListNode p1 = l1,p2=l2;
            int sum = 0;
            while(p1 != null || p2 != null){
                if(p1 != null){
                    sum += p1.val;
                    p1 = p1.next;
                }
                if(p2 != null){
                    sum += p2.val;
                    p2 = p2.next;
                }
                cur.next = new ListNode(sum % 10);
                sum /= 10;
                cur = cur.next;
            }
            if(sum == 1){
                cur.next = new ListNode(1);
            }
            return dummy.next;
        }
    }
    
    
    

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

    3.1 题目描述

    给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
    示例 1:
    输入: "abcabcbb"
    输出: 3
    解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
    示例 2:

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

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

    3.2 解题思路

    使用HashMap存储字符和位置
    使用一个变量res记录当前最大无重复长度
    使用一个变量i记录当前遍历的index
    使用一个变量j计算当前无重复的起始值

    如果当前的元素在map中已经存在了,则j在原先的重复字符的位置上往后挪一位
    j = max(j,map.get(a)+1)

    重新计算最大无重复字符个数
    res = max(res,i-j+1)

    3.3 解法

    时间复杂度为(O(n))
    空间复杂度为(O(n))

    
    class Solution {
        public int lengthOfLongestSubstring(String s) {
            if (s == null || s.length() == 0) {
                return 0;
            }
            Map<Character, Integer> map = new HashMap<>();
            int res = 0;
            for (int i = 0, j = 0; i < s.length(); i++) {
                if (map.containsKey(s.charAt(i))) {
                    j = Math.max(j, map.get(s.charAt(i)) + 1);
                }
                map.put(s.charAt(i), i);
                res = Math.max(res, i - j + 1);
            }
            return res;
        }
    }
    
    
    

    四、寻找两个有序数组的中位数

    4.1 题目描述

    给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
    请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
    你可以假设 nums1 和 nums2 不会同时为空。

    示例 1:
    nums1 = [1, 3]
    nums2 = [2]
    则中位数是 2.0

    示例 2:
    nums1 = [1, 2]
    nums2 = [3, 4]
    则中位数是 (2 + 3)/2 = 2.5

    十一、寻找两个有序数组的中位数

    给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
    
    说明:你不能倾斜容器,且 n 的值至少为 2。
    
    

    11.2 解题思路

    11.3 解法

    
    class Solution {
        public int maxArea(int[] height) {
            int l = 0;
            int r = height.length - 1;
            int maxArea = 0;
            while (l < r) {
                int maxHeight = height[l] < height[r] ? height[l] : height[r];
                int area = maxHeight * (r - l);
                if (area > maxArea) {
                    maxArea = area;
                }
                if (height[l] < height[r]) {
                    l++;
                } else {
                    r--;
                }
            }
            return maxArea;
        }
    }
    
    

    二十、有效的括号

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

    20.3 解法

    
    import java.util.Stack;
    
    /**
     * @author Michael Fang
     * @since 2019-08-08
     */
    public class Solution {
    
        public boolean isValid(String s) {
            char[] charArray = s.toCharArray();
            Stack stack = new Stack();
            for (char c : charArray) {
                if (stack.isEmpty()) {
                    stack.add(c);
                    continue;
                }
                String result = String.valueOf(stack.peek()) + String.valueOf(c);
                if (result.equals("{}") || result.equals("[]") || result.equals("()")) {
                    stack.pop();
                } else {
                    stack.add(c);
                }
            }
            return stack.isEmpty();
        }
    
    }
    
    
    

    参考文档

    [1]: LeetCode官网
    [2]: 花花酱LeetCode

  • 相关阅读:
    Notes of the scrum meeting(12.7)
    Notes of the scrum meeting(12.5)
    事后分析报告(M1阶段)
    锁屏软件发布说明
    Android 锁屏软件MemoryDebris测试报告
    锁屏软件功能介绍
    Notes of the scrum meeting(11/4)
    Notes of the scrum meeting(11/3)
    Notes of the scrum meeting(11/2)
    SCRUM 12.17
  • 原文地址:https://www.cnblogs.com/fonxian/p/10854658.html
Copyright © 2011-2022 走看看