LeetCode刷题总结【一】

前言

第一周刷LeetCode,好久没有写算法题,有点手生,但总体表现还是很棒,最起码将这个计划坚持了下来。有天下班回到家累的一动不想动,但最后还是坚持起来刷了一道题。废话少说,先写题解,希望下周可以继续加油!

题解

Two Sum

原题描述:

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

难度:**

题目大意:从一个整型数组中找出两个数相加之和等于目标值target,给出这两个数字的下标。

解题思路:用HashMap建立数组元素与目标整数的差的映射,key为number[i],value为下标,根据HashMap.containsKey()判断是否存在,若存在则输出相应下标即可。

代码:

public int[] twoSum(int[] nums, int target) {
        int[] result = new int[2];
        HashMap keyStore = new HashMap<>();
        for(int i = 0; i < nums.length; i++) {
            int anotherKey = target - nums[i];
            if (keyStore.containsKey(anotherKey)) {
                result[0] = (int) keyStore.get(target - nums[i]);
                result[1] = i;
                if (result[0] != result[1]) {
                    return result;
                }
            }
            keyStore.put(nums[i], i);
        }
        return result;
    }

时间复杂度: O(n)

空间复杂度: O(n)

耗时: 9ms

膜拜最优解:(3ms)

 public int[] twoSum(int[] nums, int target) {
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        //找出数组中最大值与最小值
        for (int num : nums) {
            if (num < min) {
                min = num;
            }
            if (num > max) {
                max = num;
            }
        }
        int validMin = Math.max(min, target - max);
        int validMax = Math.min(max, target - min);
        int length = validMax - validMin + 1;
        int[] array = new int[length];
        int offset = validMin;
        Arrays.fill(array, -1);

        for(int i = 0 ; i != nums.length ; ++i) {
            int num = nums[i];
            if (num >= validMin && num <= validMax) {
                int firstIndex = array[num - offset];
                if (firstIndex == -1) {
                    int diff = target - num;
                    array[diff - offset] = i;
                } else {
                    return new int[]{firstIndex, i};
                }
            }
        }
        throw null;
    }

Add Two Numbers

原题描述:

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8

难度:**

题目大意:给两个链表,将他们的每个结点依次相加,如果需要进位,则将进位与下个节点相加,最后给出相加后的链表。

解题思路:题目很简单,只需要遍历链表,依次相加即可。需要注意的是结果可能会越界,所以需要依次逐位相加。

代码:

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {               
        int tempSum = 0;
        ListNode head = new ListNode(0);
        ListNode pListNode = head;
        while(l1 != null || l2 != null || tempSum != 0) {
            if (l1 != null) {
                tempSum += l1.val; 
                l1 = l1.next;
            }

            if (l2 != null) {
                tempSum += l2.val;
                l2 = l2.next;
            }

            //逐位相加,不会越界……
            ListNode node2 = new ListNode(tempSum % 10);  
            pListNode.next = node2;
            pListNode = pListNode.next;
            tempSum /= 10;
        }
        return head.next;
    }

时间复杂度: O(max(m, n))

空间复杂度: O(max(m,n))

耗时: 60ms

膜拜最优解(44ms)

 public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);

        int carry = 0;
        ListNode cur = dummy;
        while(l1 != null && l2 != null) {
            cur.next = new ListNode((carry + l1.val + l2.val) % 10);
            cur = cur.next;
            carry = (carry + l1.val + l2.val) / 10;
            l1 = l1.next;
            l2 = l2.next;
        }

        while(l1 != null) {
            cur.next = new ListNode((carry + l1.val) % 10);
            cur = cur.next;
            carry = (carry + l1.val) / 10;
            l1 = l1.next;
        }

        while(l2 != null) {
            cur.next = new ListNode((carry + l2.val) % 10);
            cur = cur.next;
            carry = (carry + l2.val) / 10;
            l2 = l2.next;
        }

        if(carry > 0)
            cur.next = new ListNode(carry);

        return dummy.next;
    }

Longest Substring Without Repeating Characters

原题描述:

Given a string, find the length of the longest substring without repeating characters.

Examples:

Given “abcabcbb”, the answer is “abc”, which the length is 3.

Given “bbbbb”, the answer is “b”, with the length of 1.

Given “pwwkew”, the answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring.

难度:**

题目大意:求最长无重复子串的长度

解题思路:题目很简单,用HashMap将每个字符和对应下标存起来,每次存之前判断当前map中是否有重复的key,如果有,判断重复的字母是否在起始点n之后,最后找出最长的长度。

代码:

 public int lengthOfLongestSubstring(String s) {
      Map map = new HashMap<>();
        int maxLength=0,n = 0;
        for (int i = 0; i < s.length(); i++) {
            char c =s.charAt(i);
            if (map.containsKey(c)) {
                n = map.get(c) + 1 > n ? map.get(c) + 1 : n;
            }
            if (i - maxLength + 1 > n) {
                maxLength = i - n + 1;
            }
            map.put(c, i);
        }
        return maxLength;
    }

时间复杂度: O(n)

空间复杂度: O(n)

耗时: 51ms

膜拜最优解(35ms)

 public int lengthOfLongestSubstring(String s) {
        if (s.length() == 0) return 0;
        // for ASCII char sequence, use this as a hashmap
        int[] idx = new int[160];
        //initaize arr to -1 inorder to correct calculate interval
        for(int i = 32 ; i < idx.length; i++) {
            idx[i] = -1;
        }
        int max = 0, m = 0;
        for (int i = 0; i < s.length(); i++){
            int ascii = (int) (s.charAt(i));
            m = Math.max(idx[ascii] + 1, m);
            idx[ascii] = i;
            max = Math.max(max, i - m + 1);
        }
        return max;
    }

你可能感兴趣的:(【算法】)