Leetcode 100 Liked Questions

来源:互联网 发布:合同软件 编辑:程序博客网 时间:2024/05/20 22:02

1. 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,返回这两个数组成的数组;如果遍历完成没有找到结果,则返回null(题中假定有且仅有一解)。

  • 如果题中给出数组是有序的,在遍历中发现两数相加大于target,可以直接continue,开始下一个循环。

Java代码:

public class Solution {    public int[] twoSum(int[] nums, int target) {        int len=nums.length;            for(int i=0;i<len;i++){                for(int j=0;j<len;j++){                    if(i==j)                        continue;                    if(nums[i]+nums[j]==target){                        int[] result={i,j};                        return result;                    }                }            }            return null;    }}

2. 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.

Example:

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 0 -> 8

思路:

  • 给定两个非空链表用于表示两个非负整数,每位占一个节点,反序存放,求和。考虑常规遍历两个链表,每位相加,设置一个int变量用于存储进位信息即可。

Java代码:

/** * Definition for singly-linked list. * public class ListNode { *     int val; *     ListNode next; *     ListNode(int x) { val = x; } * } */public class Solution {    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {        ListNode head = new ListNode(0);        ListNode point = head;        int carry = 0;        while(l1 != null && l2!=null){            int sum = carry + l1.val + l2.val;            point.next = new ListNode(sum % 10);            carry = sum / 10;            l1 = l1.next;            l2 = l2.next;            point = point.next;        }        while(l1 != null) {            int sum =  carry + l1.val;            point.next = new ListNode(sum % 10);            carry = sum /10;            l1 = l1.next;            point = point.next;        }        while(l2 != null) {            int sum =  carry + l2.val;            point.next = new ListNode(sum % 10);            carry = sum /10;            l2 = l2.next;            point = point.next;        }        if (carry != 0) {            point.next = new ListNode(carry);        }        return head.next;    }}

3. 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.

思路:
声明两个整型i,j和一个127大小的数组(用于保存ascii字符是否在之前出现过)。i,j看作扫描字符串的指针,j是快指针,i是慢指针。

也就是说,j标记字符串的每两个重复字符的后一个,i标记前一个。用(j-i)来更新maxlen。

j每扫描一个字符就在数组中修改该字符的状态为true,i跟进的时候将扫描过的字符再变成false。

Java代码:

public class Solution {    public int lengthOfLongestSubstring(String s) {        int len=s.length();        int i=0,j=0,maxlen=0;        boolean[] ex = new boolean[127];        while(j<len){            if(ex[s.charAt(j)]){                maxlen=maxlen>(j-i)?maxlen:(j-i);                while(s.charAt(i)!=s.charAt(j)){                    ex[s.charAt(i)]=false;                    i++;                }                i++;j++;            }else {                ex[s.charAt(j)]=true;                j++;            }        }        /*这一句很重要,很容易被忽略!*/        maxlen=maxlen>(len-i)?maxlen:(len-i);        return maxlen;    }}

4. Median of Two Sorted Arrays

There are two sorted arrays nums1 and nums2 of size m and n
respectively.

Find the median of the two sorted arrays. The overall run time
complexity should be O(log (m+n)).

Example 1:

nums1 = [1, 3]nums2 = [2]The median is 2.0

Example 2:

nums1 = [1, 2]nums2 = [3, 4]The median is (2 + 3)/2 = 2.5

思路:

  1. 两个数组排序生成一个数组,返回中位数。时间复杂度O(n),空间复杂度O(n)。
  2. 在两个数组中按从小到大的顺序数(m+n)/2个数,即得中位数。时间复杂度O(n),空间复杂度O(1)。
  3. 分治法,可以延伸为找两个数组中大小排第k位的数。如果nums1[k/2]<nums2[k/2],则nums1[k/2]及之前的数都不可能是第k位的数,就可以从nums1的k/2位继续递归。时间复杂度O(log(m+n)),空间复杂度O(1)。
    一些细节问题:
    1. 假定m总是小于n的,若m>n,则nums1,nums2的参数位置颠倒。
    2. 当m+n为偶数时需要找中间的两个数。
    3. 因为Java没有指针,所以参数中还需要有pos1和pos2来标明当前数组的“头部”在哪里。
    4. 边界:当nums1长度为0时,直接返回nums2[k-1];当k==1时,返回Math.min(nums1[pos1], nums2[pos2])。

更多详细解析参看:
https://segmentfault.com/a/1190000002988010

5. Longest Palindromic Substring

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example:

Input: "babad"Output: "bab"Note: "aba" is also a valid answer.

Example:

Input: "cbbd"Output: "bb"

思路:

相似问题:最长回文子序列。注意子序列和子串的区别。

回到这个问题:

  1. 穷举所有子串,判断是否为回文,再取最长的。时间复杂度:O(n3)

  2. 以字符串中的一个字符为回文的中心,向两边扩散,直到不符合回文要求为止,记录最长的子串及其长度。时间复杂度:O(n2)

  3. 动态规划。如果下标 i+1 到 j-1 的子串是回文的,且下标为 i j 的两个字符相等,那么 i 到 j 的子串也是回文的。

Java代码:

/*动态规划有两个需要注意的细节:1.输入串s为""或只包含单个字符的字符串,特殊处理,判断长度后直接返回。2.由于这个算法里处理回文的条件有s.charAt(i)==s.charAt(j),也就是说如果整个字符串s不包含相等的两个字符,最后输出的结果就为""。但事实上应该是输出第一个字符(任意一个字符都是一个特殊的回文情况,在这里我们输出第一个)*/public String longestPalindrome(String s) {        int len = s.length();        if(len == 1||len == 0)            return s;        boolean[][] palin = new boolean[len][len];        String result = "";        int maxlen=0;        for(int i = 0;i<len;i++){            for(int j=i;j>=0;j--){                if(s.charAt(i)==s.charAt(j)                 && ((i-j)<=2 || palin[i-1][j+1])){                    palin[i][j] = true;                    if(maxlen<(i-j)){                        maxlen = i-j;                        result =s.substring(j, i+1);                        System.out.println("Result:"+result);                    }                }            }        }        if (maxlen == 0)        {            result = ""+s.charAt(0);        }        return result;    }