leetcode刷题总结(1-5题)

刷 leetcode前20题的总结。

一、Two Sum

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

return [0, 1].

没啥技术含量,方法一暴力破解,两个for循环,nums[i]+nums[j]==target;

public int[] twoSum(int[] nums, int target) {
    for (int i = 0; i < nums.length; i++) {
        for (int j = i + 1; j < nums.length; j++) {
            if (nums[j] == target - nums[i]) {
                return new int[] { i, j };
            }
        }
    }
    throw new IllegalArgumentException("No two sum solution");
}

注意数组的长度是nums.length。

第二种方法是用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");
}
注意Map的初始化方式,<key,value>的格式,map.containsKey()的用法。map.get()是用value值去得到key.


二、Add Two Numbers

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

Explanation: 342 + 465 = 807.

两个链表相加的问题,注意ListNode的构建。

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    ListNode dummyHead = new ListNode(0);
    ListNode p = l1, q = l2, curr = dummyHead;
    int carry = 0;
    while (p != null || q != null) {
        int x = (p != null) ? p.val : 0;
        int y = (q != null) ? q.val : 0;
        int sum = carry + x + y;
        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 dummyHead.next;
}

注意p==null或者q=null时,加的值为0。每次new出来的节点的值为sum%10。

三、Longest Substring Without Repeating Characters

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.

最初我的答案是这样的,时间复杂度比较高

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s==null||s.length()==0)
        {
            return 0;
        }
        HashMap<Character,Integer> map =new HashMap<Character,Integer>();
        int counter = 0 ;
        int max = 0;
        for(int i = 0 ; i < s.length(); i++)
        {
            if(!map.containsKey(s.charAt(i)))
            {
                map.put(s.charAt(i), i);
                    counter++;
            }
            else{
                i = map.get(s.charAt(i));
                map = new HashMap<Character,Integer>();
                counter=0;
            }
            max = Math.max(max , counter);
        }
        return max;
    }
}
用了hashmap,每次遇到不重复的char就存入map,并且设置了一个计数器来计数,用max来取最大。每次遇到重复的元素就把hashmap清零重新创建,把i回退到重复元素那里。
class Solution {
    public int lengthOfLongestSubstring(String s) {
        if (s == null || s.length() == 0) {
		return 0;
	}
	int result = 0;
	int slow = 0;
	int fast = 0;
	Set<Character> set = new HashSet<>();
	while (fast < s.length()) {
		if (set.add(s.charAt(fast))) {
			fast++;
			result = Math.max(fast - slow, result);
		} else {
			set.remove(s.charAt(slow++));
		}
	}
	return result;
    }
}

比较好的一个答案,利用了set里面元素不重复的特性。注意set.add()的用法:

如果Set集合中不包含要添加的对象,则添加对象并返回true;否则返回false。

slow指向的是重复元素的标号,每次只删除重复元素,不用把表清零。

四、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)).

nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5

这个题乍一看挺简单,直接合并两个数组,然后Arrays.sort()排序,取中间的就行了,但是有时间复杂度的限制。

原问题可以成一个寻找第k小数的问题。

一个小技巧: total & 0x1来判断total是奇数还是偶数。

求的是中位数,也就是说m+n是奇数的话 k=(m+n)/2+1,m+n为偶数是k=(m+n)/2 和(m+n)/2+1。

可以用递归的思想。每次比较两个数组中最中间那个元素,假设nums1[k/2]<num2[k/2],那么就取nums1[k/2]到nums1[m],然后依次求下去,直到nums1[k/2]==nums2[k/2]或者有个数组为空或者k==1.

int get_kth(int a[],int b[],int lena,int lenb,int k)
{
    if(lena > lenb)//保证第一个数组元素更少
        return get_kth(b, a, lenb, lena, k);
    if(lena == 0)
        return b[k-1];
    if(k == 1)
        return min(a[0],b[0]);
    int mida = min(k/2,lena), midb = k-mida;
    if(a[mida-1] == b[midb-1])
        return a[mida-1];
    else if(a[mida-1] < b[midb-1])
        return get_kth(a+mida, b, lena-mida, lenb, k-mida);
    else
        return get_kth(a, b+midb, lena, lenb-midb, k-midb);
}

int min(int a,int b)
{
    return a<b?a:b;
}

double findMedianSortedArrays(int* nums1, int n, int* nums2, int m) 
{
    int sum = n+m;
    if(sum%2 == 1)//奇数
        return get_kth(nums1,nums2,n,m,sum/2+1);
    else
        return ((get_kth(nums1, nums2, n, m, sum/2))+(get_kth(nums1, nums2, n, m, sum/2+1)))/2.0;
} 

五、Longest Palindromic Substring

Input: "babad"
Output: "bab"

Note: "aba" is also a valid answer.

这题比较简单,注意 substring的用法

public String substring(int beginIndex, int endIndex)
第一个int为开始的索引,对应String数字中的开始位置,
第二个是截止的索引位置,对应String中的结束位置
1、取得的字符串长度为:endIndex - beginIndex;
2、从beginIndex开始取,到endIndex结束,从0开始数,其中不包括endIndex位置的字符
如:

"hamburger".substring(4, 8) returns "urge"

定义一个方法Palindrome,输入起始位置和结束位置去找以i为中心的回文数,i循环s.length()次,比较得到最长的回文数。

还要注意 abba和aba这两种,所以要输入Palindrome(s , i , i)和Palindrome(s , i , i+1)。注意边界条件。

class Solution {
    public String longestPalindrome(String s) {
        if(s.length()==1)
        {
            return s;
        }
        String tmp = s.substring(0,1);
        String longest = tmp;
        for(int i = 0;i<s.length()-1;i++){
            
            tmp = Palindrome(s , i , i);
            if(tmp.length()>longest.length()){
                longest = tmp;
            }
            tmp = Palindrome(s , i , i+1);
            if(tmp.length()>longest.length()){
                longest = tmp;
            }
        }
         return longest;
    }
    public static String Palindrome(String s, int begin, int end) {
    while(begin>=0&&end<s.length()&&s.charAt(begin)==s.charAt(end)){
        begin--;
        end++;
    }
        return s.substring(begin+1,end);
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值