LeetCode Top100之1,2,3题

1. 两数之和

① 题目描述
  • 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
  • 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
  • 示例:

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

② 暴力求解
public int[] twoSum(int[] nums, int target) {
    
    
    for (int i = 0; i < nums.length - 1; i++) {
    
    
        for (int j = i + 1; j < nums.length; j++) {
    
    
            if (nums[i] + nums[j] == target) {
    
    
                return new int[]{
    
    i,j};
            }
        }
    }
    throw new IllegalArgumentException("No two sum solution");
    
}
③ 两次hashMap遍历
public int[] twoSum(int[] nums, int target) {
    
    
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < nums.length; i++) {
    
    
        map.put(nums[i], i);
    }
    for (int i = 0; i < nums.length; i++) {
    
    
        int complement = target - nums[i];
        if (map.containsKey(complement) && map.get(complement) != i) {
    
    
            return new int[] {
    
     i, map.get(complement) };
        }
    }
    throw new IllegalArgumentException("No two sum solution");
}

2. 两数相加

① 题目描述
  • 给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
  • 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
  • 您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
  • 示例:

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

② 情况分析

在这里插入图片描述

③ 元素加法
  • 总结所有的情况,首先要考虑carry,carry可能是最后一位的加法进位,导致链表长度变长。
  • 针对有链表为null和链表长度不一致的情况,巧妙使用||运算符,只有当两个链表的都为null时,才停止加法计算。
  • 使用好辅助的链表,一个指向初始node,一个用于指向当前node。
  • 代码如下:
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    
    
    ListNode result = new ListNode(0);
    ListNode p = l1, q = l2, curr = result;
    int carry = 0;
    while (p != null || q != null) {
    
    
        int x = (p != null) ? p.val : 0;
        int y = (q != null) ? q.val : 0;
        int sum = x + y + carry;
        carry=sum/10;
        curr.next=new ListNode(sum%10);
        curr=curr.next;
        if(p!=null){
    
    
            p=p.next;
        }
        if(q!=null){
    
    
            q=q.next;
        }
    }
    if (carry!=0){
    
    
        curr.next=new ListNode(carry);
    }
    return result.next;
}

3. 无重复字符的最长子串

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

输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。

  • 示例 2:

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

  • 示例 3:

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

② 暴力求解(Time Limit Exceeded)
public int lengthOfLongestSubstring(String s) {
    
    
    if (s.length()==0){
    
    
        return 0;
    }
    int max=1;
    for (int i=0;i<s.length()-1;i++){
    
    
        for (int j=i+1;j<s.length();j++){
    
    
            if (helper(s,i,j)){
    
    
                max=Math.max(max,j-i+1);
            }else{
    
    // 从start开始的串有重复字符,后面的不用再判断
                break;
            }
        }
    }
    return max;
}

public boolean helper(String s, int start, int end) {
    
    
    Set<Character> set = new HashSet<>(); // 利用set存储不重复的字符
    for (int i = start; i <= end; i++) {
    
    
        char ch=s.charAt(i);
        if (set.contains(ch)){
    
    
            return false;
        }
        set.add(ch);
    }
    return true;
}
③ 滑动窗口
  • 对滑动窗口的介绍:

A sliding window is an abstract concept commonly used in array/string problems. A window is a range of elements in the array/string which usually defined by the start and end indices, i.e. [i, j) (left-closed, right-open). A sliding window is a window “slides” its two boundaries to the certain direction. For example, if we slide [i, j) to the right by 11 element, then it becomes [i+1, j+1)(left-closed, right-open).

public int lengthOfLongestSubstring(String s) {
    
    
    int len=s.length();
    int i=0,j=0,max=0;
    Set<Character> set=new HashSet<>();
    while(i<len&&j<len){
    
    
       if(!set.contains(s.charAt(j))) {
    
    
           set.add(s.charAt(j++));
           max=Math.max(max,j-i);// 每一步都要更新max
       }else{
    
    
           set.remove(s.charAt(i++));// 去除重复的字符从下一个位置开始查找不重复字符的子串
       }
    }
    return max;
}

猜你喜欢

转载自blog.csdn.net/u014454538/article/details/90257502