刷 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 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的初始化方式,二、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 map =new HashMap();
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();
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 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] 五、Longest Palindromic Substring Input: "babad" Note: "aba" is also a valid answer. 这题比较简单,注意 substring的用法 public String substring(int beginIndex, int endIndex) "hamburger".substring(4, 8) returns "urge" 定义一个方法Palindrome,输入起始位置和结束位置去找以i为中心的回文数,i循环s.length()次,比较得到最长的回文数。 还要注意 abba和aba这两种,所以要输入Palindrome(s , i , i)和Palindrome(s , i , i+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
Output: "bab"
第一个int为开始的索引,对应String数字中的开始位置,
第二个是截止的索引位置,对应String中的结束位置
1、取得的字符串长度为:endIndex - beginIndex;
2、从beginIndex开始取,到endIndex结束,从0开始数,其中不包括endIndex位置的字符
如: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