LC3 Longest Substring Without Repeating Characters
Problem
Given a string, find the length of the longest substring without repeating characters.
Example 1:
1
2
3 Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.Example 2:
1
2
3 Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.Example 3:
1
2
3
4 Input: "pwwkew"
Output: 3
Explanation: 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.
Think
滑动窗口法,设窗口为(i, j],则遍历字符串,设置一个hashmap保存所有字符出现的位置
假如当前字符出现过,则需要将窗口的左边界移到上一次出现的位置;
然后更新res = max(res, j - i),并将当前字符和位置保存到hashmap里
Code
1 | int lengthOfLongestSubstring(string s) { |
LC15 3Sum
Problem
Given an array
nums
of n integers, are there elements a, b, c innums
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.
Example:
1
2
3
4
5
6
7 Given array nums = [-1, 0, 1, 2, -1, -4],
A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]
Think
主要的想法是固定一个,求另外两个。为确保不重复,首先对数组排序,假设a最小,则a只能出现在<=0的部分;
剩下部分即为用双指针求解b+c=-a的所有b和c(对每一个可能的a),注意判断重复值
Code
1 | vector<vector<int>> threeSum(vector<int>& nums) { |
LC16 3Sum Closest
Problem
Given an array
nums
of n integers and an integertarget
, find three integers innums
such that the sum is closest totarget
. Return the sum of the three integers. You may assume that each input would have exactly one solution.Example:
1
2
3 Given array nums = [-1, 2, 1, -4], and target = 1.
The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
Think
和上一题3Sum的想法类似,使用的也是固定一个,求另外两个的方法
Code
1 | int threeSumClosest(vector<int>& nums, int target) { |
LC18 4Sum
Problem
Given an array
nums
of n integers and an integertarget
, are there elements a, b, c, and d innums
such that a + b + c + d =target
? Find all unique quadruplets in the array which gives the sum oftarget
.Note:
The solution set must not contain duplicate quadruplets.
Example:
1
2
3
4
5
6
7
8 Given array nums = [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]
]
Think
依然是和3Sum类似的想法,先固定一个,然后对剩下的数组用3Sum的算法即可;注意剪枝条件。
Code
1 | vector<vector<int>> fourSum(vector<int>& nums, int target) { |
LC19 Remove Nth Node From End of List
Problem
Given a linked list, remove the n-th node from the end of list and return its head.
Example:
1
2
3 Given linked list: 1->2->3->4->5, and n = 2.
After removing the second node from the end, the linked list becomes 1->2->3->5.Note:
Given n will always be valid.
Follow up:
Could you do this in one pass?
Think
双指针
快指针先走n步,然后快慢指针同步向后走,直到快指针到达链表的尾端
Code
1 | ListNode* removeNthFromEnd(ListNode* head, int n) { |
LC26 Remove Duplicates from Sorted Array
Problem
Given a sorted array nums, remove the duplicates in-place such that each element appear only once and return the new length.
Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
Example 1:
1
2
3
4
5 Given nums = [1,1,2],
Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively.
It doesn't matter what you leave beyond the returned length.Example 2:
1
2
3
4
5 Given nums = [0,0,1,1,1,2,2,3,3,4],
Your function should return length = 5, with the first five elements of nums being modified to 0, 1, 2, 3, and 4 respectively.
It doesn't matter what values are set beyond the returned length.Clarification:
Confused why the returned value is an integer but your answer is an array?
Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well.
Internally you can think of this:
1
2
3
4
5
6
7
8 // nums is passed in by reference. (i.e., without making a copy)
int len = removeDuplicates(nums);
// any modification to nums in your function would be known by the caller.
// using the length returned by your function, it prints the first len elements.
for (int i = 0; i < len; i++) {
print(nums[i]);
}
Think
设置offset,当读到相同的数字的时候offset自增,然后将nums[i]处的数字放在nums[i - offset]处;
最后返回长度为n-offset。
Code
1 | int removeDuplicates(vector<int>& nums) { |
LC27 Remove Element
Problem
Given an array nums and a value val, 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 by modifying the input array in-place with O(1) extra memory.
The order of elements can be changed. It doesn’t matter what you leave beyond the new length.
Example 1:
1
2
3
4
5 Given nums = [3,2,2,3], val = 3,
Your function should return length = 2, with the first two elements of nums being 2.
It doesn't matter what you leave beyond the returned length.Example 2:
1
2
3
4
5
6
7 Given nums = [0,1,2,2,3,0,4,2], val = 2,
Your function should return length = 5, with the first five elements of nums containing 0, 1, 3, 0, and 4.
Note that the order of those five elements can be arbitrary.
It doesn't matter what values are set beyond the returned length.Clarification:
Confused why the returned value is an integer but your answer is an array?
Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well.
Internally you can think of this:
1
2
3
4
5
6
7
8 // nums is passed in by reference. (i.e., without making a copy)
int len = removeElement(nums, val);
// any modification to nums in your function would be known by the caller.
// using the length returned by your function, it prints the first len elements.
for (int i = 0; i < len; i++) {
print(nums[i]);
}
Think
类似上一题,但是注意当值不相等时才写入,相等则不写入
Code
1 | int removeElement(vector<int>& nums, int val) { |
Review
双指针一般是两种情况:
- 两个指针之间存在差值关系或者倍数关系,一般这种关系正是题目中的核心要求;
- 两个指针分别从数组的一头一尾进行遍历,直到两者相遇,一般这种情况多出现在有序数组,或者存在某种逻辑关系(一般不会直接给出)使得我可以选择是左边的指针右移还是右边的指针左移