第一部分:Array
twoSum问题
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].
自己的暴力算法解答(带输入输出):时间复杂度:O(n^2)
同学讲解后使用双指针解答:自己刚开始使用Map,自己感觉思路特别清晰,但是不知道Map的map.put(nums[i],i)如果nums[i]相同会覆盖,但是双指针仍然需要一个值与索引的这样一个集合,所以就需要再建立一个新的类来存放值与索引。
经过同学的细心教导后的双指针(自己本来定义的是Map类,但是LeetCode提示这个类已经被定义,所以编译不通过):
LeetCode别人的优质解答:
解题思路:
代码的(判断nums[i]或者是target-nums[i]都可以):
twoSum引伸出来的双指针问题:
Container with most water--LeetCode11题
Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container and n is at least 2.
题目的大致意思就是给定义个数组,然后根据相应的索引值垂直x轴划线,然后从任意选择两条线段,根据木桶原理进行蓄水,找到蓄水最多的两条线段。我首先采用暴力遍历的方式进行计算,这样的话时间复杂度是O(N^2),通过LeetCode测试时,时间超出限制。
然后看LeetCode上面的优质解答,代码如下:
这样就延伸出一系列的Two Points(双指针)问题,以下题目全部来自微信公众号:光影键盘侠。
Move Zeros---LeetCode第283道题
给一个数组 nums 写一个函数将
0
移动到数组的最后面,非零元素保持原数组的顺序注意:
1.必须在原数组上操作
2.最小化操作数
解题思路(双指针分别是指向数组的和指向0的指针):
代码:
Remove Duplicates from Sorted Array---LeetCode第26道题
给一个整数数组,去除重复的元素。
你应该做这些事
1.在原数组上操作
2.将去除重复之后的元素放在数组的开头
3.返回去除重复元素之后的元素个数注意是排好序的数组,例如输入 [0 0 1 2 3 3]输出4
解题思路:两个指针一个进行遍历,一个记录重复的长度,相同的话长度加1,不同的话左移--代码如下:
Implement strStr()--LeetCode第28题
对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始)。如果不存在,则返回
-1
。Implement strStr().
Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
思路:(注意:i的范围很容易出错,注意是haystack.length()-needle.length()+1而不是简单的haystack.length())两个指针分别从两个字符串进行遍历,判断haystack有没有needle
Container with most water--LeetCode11题
Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container and n is at least 2.
题目的大致意思就是给定义个数组,然后根据相应的索引值垂直x轴划线,然后从任意选择两条线段,根据木桶原理进行蓄水,找到蓄水最多的两条线段。我首先采用暴力遍历的方式进行计算,这样的话时间复杂度是O(N^2),通过LeetCode测试时,时间超出限制。
然后看LeetCode上面的优质解答,代码如下:
这样就延伸出一系列的Two Points(双指针)问题,以下题目全部来自微信公众号:光影键盘侠。
Move Zeros---LeetCode第道题
给一个数组 nums 写一个函数将
0
移动到数组的最后面,非零元素保持原数组的顺序注意:
1.必须在原数组上操作
2.最小化操作数
解题思路(双指针分别是指向数组的和指向0的指针):
代码:
Remove Duplicates from Sorted Array---LeetCode第道题
给一个整数数组,去除重复的元素。
你应该做这些事
1.在原数组上操作
2.将去除重复之后的元素放在数组的开头
3.返回去除重复元素之后的元素个数注意是排好序的数组,例如输入 [0 0 1 2 3 3]输出4
解题思路:两个指针一个进行遍历,一个记录重复的长度,相同的话长度加1,不同的话左移--代码如下:
Implement strStr()--LeetCode第28题
对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始)。如果不存在,则返回
-1
。Implement strStr().
Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
思路:(注意:i的范围很容易出错,注意是haystack.length()-needle.length()+1而不是简单的haystack.length())两个指针分别从两个字符串进行遍历,判断haystack有没有needle
Sort Colors--LeetCode第75题
给定一个包含红,白,蓝且长度为 n 的数组,将数组元素进行分类使相同颜色的元素相邻,并按照红、白、蓝的顺序进行排序。
我们可以使用整数 0,1 和 2 分别代表红,白,蓝。
样例
给你数组 [1, 0, 1, 2], 需要将该数组 in-place 排序为 [0, 1, 1, 2]。
解题思路:本题其实是一个升级版的双指针问题,借用moveZeros题目的思路,只不过要同时move两个数。实际就是一个三指针问题,一个指向零的指针,一个指向2的指针,再一个遍历的指针。 但是一定要注意对2进行交换的时候可能会出现将后面的2与前面的2互换的情况。
Minimum Size Subarray Sum--LeetCode第209道题
给定一个由 n 个整数组成的数组和一个正整数 s ,请找出该数组中满足其和 ≥ s 的最小长度子数组。如果无解,则返回 -1。
样例
给定数组 [2,3,1,2,4,3] 和 s = 7, 子数组 [4,3] 是该条件下的最小长度子数组。
解题思路:定义一个left指针记录子数组的起始位置,然后再定义一个i指针进行遍历。![]()
Longest Substring Without Repeating Characters --LeetCode第3题
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.解题思路:定义两个指针,右指针对字符串数组进行遍历,map中不包含的话就放入map,否则的话,将左指针移到重复字符的下一位,继续遍历。
LeetCode第27题 Remove Element
Given an array and a value, remove all instances of that value in place and return the new length.
Do not allocate extra space for another array, you must do this in place with constant memory.
The order of elements can be changed. It doesn't matter what you leave beyond the new length.
Example:
Given input array nums =[3,2,2,3]
, val =3
Your function should return length = 2, with the first two elements of nums being 2.
解题思路:利用moveZeros的思想。
1 public class Solution { 2 public int removeElement(int[] nums, int value) { 3 if(nums == null || nums.length == 0) { 4 return 0; 5 } 6 int i = 0; int valpoint = 0; 7 while(i < nums.length) { 8 if(nums[i] != value) { 9 int temp = nums[i]; 10 nums[i] = nums[valpoint]; 11 nums[valpoint] = temp; 12 i++; 13 valpoint++; 14 } else i++; 15 } 16 return valpoint;//第一次写成了nums.length-valpoint出错 17 } 18 }
LeetCode优质解答:大体思路跟moveZeros相同,直接用begin记录不同于value的个数(通过赋值的方式实现)。(删除不一定真的删除,将需要删除的元素后放,不需要删除的放在前面)
1 public class Solution { 2 public int removeElement(int[] nums, int value) { 3 if(nums == null || nums.length == 0) { 4 return 0; 5 } 6 int valpoint = 0; 7 for(int i = 0; i < nums.length; i++) { 8 if(nums[i] != value) { 9 nums[valpoint] = nums[i]; 10 valpoint++; 11 } 12 } 13 return valpoint; 14 } 15 }
Array--threeSum问题
LeetCode第15题
threeSum问题整整花了一天的时间,天哪,要崩溃了,但是这种做法真的是不可取。下面这个帖子建议大家看看。
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note: The solution set must not contain duplicate triplets.
For example, given array S = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
我的思路是: 先将数组排好序,然后一个一个放入ArrayList,然后对数组进行遍历,在它的右边放置两个指针,然后就是twoSum问题,target就是当前遍历数组的相反数。下面今天改了一天第一次Accepted的结果。
LeetCode别人的优质解答:(注意LinkedList的插入和删除的性能比ArrayList好,因此将程序中第4行换成LinkedList性能就提高了60%)
大神同学给的这种题目的模板:
3Sum Closest--LeetCode第16题
Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
For example, given array S = {-1 2 1 -4}, and target = 1. The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
解题思路:跟之前的threeSum情况一样,设置三个指针,分别是遍历指针、左指针、右指针,然后求和,如果小于target,左指针右移,否则右指针左移。代码如下:
1 public class Solution { 2 public int threeSumClosest(int[] nums, int target) { 3 if(nums == null || nums.length == 0) { 4 return 0; 5 } 6 Arrays.sort(nums); 7 int result = nums[0] + nums[1] + nums[nums.length - 1]; 8 for(int i = 0; i < nums.length - 2; i++) { 9 int left = i + 1; int right = nums.length - 1; 10 while(left < right) { 11 int sum = nums[i] + nums[left] + nums[right]; 12 if(sum < target) { 13 left++; 14 } else if(sum > target) { 15 right--; 16 } else{ 17 return sum; 18 } 19 if(Math.abs(result - target) > Math.abs(sum - target)) {//判断与target的距离 20 result = sum; 21 } 22 } 23 } 24 return result; 25 } 26 }
Array-4Sum问题
LeetCode第18题--4Sum
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
Note: The solution set must not contain duplicate quadruplets.
For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0. A solution set is: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]
1 //解题思路:将之前解决的3Sum问题再加一层循环,注意两层for循环中的条件 2 public class Solution { 3 public List<List<Integer>> fourSum(int[] nums, int target) { 4 List<List<Integer>> result = new LinkedList<>(); 5 if(nums == null || nums.length < 4) { 6 return result; 7 } 8 Arrays.sort(nums);//注意一般情况都是要先进行排序的 9 for(int first = 0; first < nums.length - 3; first++) { 10 if(first > 0 && nums[first] == nums[first - 1]) { 11 continue; 12 } 13 for(int second = first + 1; second < nums.length - 2; second++) { 14 if(second > first + 1 && nums[second] == nums[second - 1]) {//这里要注意的是 second > first + 1 15 continue; 16 } 17 int left = second + 1; int right = nums.length - 1; int target1 = target - (nums[first] + nums[second]); 18 while(left < right) { 19 int sum = nums[left] + nums[right]; 20 if(sum == target1) { 21 result.add(Arrays.asList(nums[first], nums[second], nums[left], nums[right])); 22 while(left < right && nums[left] == nums[left + 1]) left++; 23 while(left < right && nums[right] == nums[right - 1]) right--; 24 left++; 25 right--; 26 } else if(sum < target1) { 27 left++; 28 } else { 29 right--; 30 } 31 } 32 } 33 } 34 return result; 35 } 36 }
Array--35题
LeetCode--35. Search Insert Position
Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
You may assume no duplicates in the array.
Here are few examples.[1,3,5,6]
, 5 → 2[1,3,5,6]
, 2 → 1[1,3,5,6]
, 7 → 4[1,3,5,6]
, 0 → 0
最简单的思路:对所有的情况进行判断。
public class Solution { public int searchInsert(int[] nums, int target) { if(nums == null || nums.length == 0) { return 0; } for(int i = 0; i < nums.length; i++) { if(target == nums[i]) return i; else if(target < nums[0]) return 0; else if(target > nums[nums.length - 1]) return nums.length; else if(target > nums[i] && target < nums[i + 1]) return i + 1; } return 0; } }
查看LeetCode别人的解答启发除了下面的(只用判断是否大于等于target):
public class Solution { public int searchInsert(int[] nums, int target) { if(nums == null || nums.length == 0) { return 0; } for(int i = 0; i < nums.length; i++) { if(nums[i] >= target) return i; } return nums.length; } }