1. 两数之和
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。
你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
class Solution {
public:
vector<int> twoSum(vector<int> &nums,int target){
unordered_map<int,int>mapping;
vector<int> a;
for(int i=0;i<nums.size();i++)
mapping[nums[i]]=i;
for(int i=0;i<nums.size();i++)
{
unsigned int result=target-nums[i];
if(mapping.find(result)!=mapping.end()&&mapping[result]>i)
{ a.push_back(i);
a.push_back(mapping[result]);
}
}
return a;
}
};
867. 转置矩阵
给定一个矩阵 A
, 返回 A
的转置矩阵。
矩阵的转置是指将矩阵的主对角线翻转,交换矩阵的行索引与列索引。
示例 1:
输入:[[1,2,3],[4,5,6],[7,8,9]]
输出:[[1,4,7],[2,5,8],[3,6,9]]
示例 2:
输入:[[1,2,3],[4,5,6]]
输出:[[1,4],[2,5],[3,6]]
提示:
1 <= A.length <= 1000
1 <= A[0].length <= 1000
class Solution {
public:
vector<vector<int>> transpose(vector<vector<int>>& A) {
int p = A.size();
int q = A[0].size();
vector<vector<int>> B(q);
for(int i=0;i<q;i++)
{
B[i].resize(p);
}
for(int i = 0; i < p; i++)
for(int j = 0; j < q; j++)
B[j][i] = A[i][j];
return B;
}
};
414. 第三大的数
给定一个非空数组,返回此数组中第三大的数。如果不存在,则返回数组中最大的数。要求算法时间复杂度必须是O(n)。
示例 1:
输入: [3, 2, 1]
输出: 1
解释: 第三大的数是 1.
示例 2:
输入: [1, 2]
输出: 2
解释: 第三大的数不存在, 所以返回最大的数 2 .
示例 3:
输入: [2, 2, 3, 1]
输出: 1
解释: 注意,要求返回第三大的数,是指第三大且唯一出现的数。
存在两个值为2的数,它们都排第二。
class Solution {
public:
int thirdMax(vector<int>& nums) {
sort(nums.begin(),nums.end());
int count=1;int p=0;
for(int i=nums.size()-1;i>0;i--)
{
if(nums[i-1]!=nums[i])
count++;
if(count==3)
{
p=i-1;
break;
}
}
if(count<3)
return nums[nums.size()-1];
else
return nums[p];
}
};
35. 搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 1:
输入: [1,3,5,6], 5
输出: 2
示例 2:
输入: [1,3,5,6], 2
输出: 1
示例 3:
输入: [1,3,5,6], 7
输出: 4
示例 4:
输入: [1,3,5,6], 0
输出: 0
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int pos = 0;
for(int i = 0; i<nums.size(); i++)
{
if(target > nums[i])
pos = i+1;
if(target == nums[i])
pos = i;
}
return pos;
}
};
189. 旋转数组
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入:[1,2,3,4,5,6,7]
和 k = 3 输出:[5,6,7,1,2,3,4]
解释: 向右旋转 1 步:[7,1,2,3,4,5,6]
向右旋转 2 步:[6,7,1,2,3,4,5]
向右旋转 3 步:[5,6,7,1,2,3,4]
示例 2:
输入: [-1,-100,3,99]
和 k = 2
输出: [3,99,-1,-100]
解释:
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]
class Solution {
public:
void rotate(vector<int>& nums, int k) {
if(k>0){
if(nums.size()>k)
{
nums.insert(nums.begin(),nums.end()-k,nums.end());
nums.erase(nums.end()-k,nums.end());
}
if(nums.size()<k)
{
int a=k%nums.size();
nums.insert(nums.begin(),nums.end()-a,nums.end());
nums.erase(nums.end()-a,nums.end());
}
}
}
};
27. 移除元素
给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1:
给定 nums = [3,2,2,3], val = 3,
函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。
你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度5
, 并且 nums 中的前五个元素为0
,1
,3
,0
, 4。 注意这五个元素可为任意顺序。 你不需要考虑数组中超出新长度后面的元素。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
for(int i = 0; i < nums.size(); i++)
if(nums[i] == val)
{
nums.erase(nums.begin()+i);
i--;}
return nums.size();
}
};
26. 删除排序数组中的重复项
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定数组 nums = [1,1,2], 函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为1
,2
你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,0,1,1,1,2,2,3,3,4], 函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为0
,1
,2
, 34
你不需要考虑数组中超出新长度后面的元素。
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
for(int i =1; i<nums.size(); i++)
if(nums[i] == nums[i-1])
{
nums.erase(nums.begin()+i);
i--;
}
return nums.size();
}
};
830. 较大分组的位置
在一个由小写字母构成的字符串 S
中,包含由一些连续的相同字符所构成的分组。
例如,在字符串 S = "abbxxxxzyy"
中,就含有 "a"
, "bb"
, "xxxx"
, "z"
和 "yy"
这样的一些分组。
我们称所有包含大于或等于三个连续字符的分组为较大分组。找到每一个较大分组的起始和终止位置。
最终结果按照字典顺序输出。
示例 1:
输入: "abbxxxxzzy"
输出: [[3,6]]
解释: "xxxx" 是一个起始于 3 且终止于 6 的较大分组
示例 2:
输入: "abc"
输出: []
解释: "a","b" 和 "c" 均不是符合要求的较大分组。
示例 3:
输入: "abcdddeeeeaabbbcd"
输出: [[3,5],[6,9],[12,14]]
说明: 1 <= S.length <= 1000
class Solution {
public:
vector<vector<int>> largeGroupPositions(string S) {
vector<vector<int>> vec;
int i;
int count=1;
for(i=0;i<S.size();i++)
{
if(S[i]==S[i+1])
count++;
if(S[i]!=S[i+1]||i==S.size()-1)
{
if(count>=3)
{
vector<int> v(2,0);
v[0]=i-count+1;
v[1]=i;
vec.push_back(v);
}
count=1;
}
}
return vec;
}
};
581. 最短无序连续子数组
给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。
你找到的子数组应是最短的,请输出它的长度。
示例 1:
输入: [2, 6, 4, 8, 10, 9, 15]
输出: 5
解释: 你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。
说明 :
- 输入的数组长度范围在 [1, 10,000]。
- 输入的数组可能包含重复元素 ,所以升序的意思是<=。
class Solution {
public:
int findUnsortedSubarray(vector<int>& nums) {
vector<int> nums1(nums.begin(),nums.end());
sort(nums1.begin(), nums1.end());
int last = 0;
vector<int> nums2;
int count = 0;
for(int i =0; i < nums.size(); i++)
{
if(nums1[i] != nums[i])
{
count++;
nums2.push_back(i);
last = i;
}
}
if(count == 0)
return 0;
count = last - nums2[0] + 1;
return count;
}
};
66. 加一
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。
示例 2:
输入: [4,3,2,1]
输出: [4,3,2,2]
解释: 输入数组表示数字 4321。
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
digits.back() +=1;
for(int i = digits.size()-1; i > 0; i--)
if(digits[i] > 9)
{
digits[i] = digits[i] % 10;
digits[i-1]++;
}
if(digits[0] > 9)
{
digits[0] = digits[0] % 10;
digits.insert(digits.begin(),1);
}
return digits;
}
};
118. 杨辉三角
在杨辉三角中,每个数是它左上方和右上方的数的和。
示例:
输入: 5
输出:
[
[1],
[1,1],
[1,2,1],
[1,3,3,1],
[1,4,6,4,1]
]
class Solution {
public:
vector<vector<int>> generate(int numRows) {
vector<vector<int>> v;
for(int i=1;i<=numRows;i++)
{
vector<int> r(i,1);
if(i>2&&i<=numRows)
{
for(int j=1;j<i-1;j++)
{
r[j]=v[i-2][j-1]+v[i-2][j];
}
}
v.push_back(r);
}
return v;
}
};
283. 移动零
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入:[0,1,0,3,12]
输出:[1,3,12,0,0]
说明:
- 必须在原数组上操作,不能拷贝额外的数组。
- 尽量减少操作次数。
class Solution {
public:
void moveZeroes(vector<int>& nums) {
if(nums.size()<2) return;
int count = 0;
for(int i=0; i<nums.size(); i++){
if(!nums[i]) count++;
else swap(nums[i-count], nums[i]);
}
return;
}
};
268. 缺失数字
给定一个包含 0, 1, 2, ..., n
中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。
示例 1:
输入: [3,0,1]
输出: 2
示例 2:
输入: [9,6,4,2,3,5,7,0,1]
输出: 8
class Solution {
public:
int missingNumber(vector<int>& nums) {
sort(nums.begin(), nums.end());
for(int i = 0; i<nums.size(); i++)
{
if(nums[i] != i)
return i;
if(nums[nums.size()-1] == i)
return i+1;
}
}
};
88. 合并两个有序数组
给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
说明:
- 初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
- 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
输出: [1,2,2,3,5,6]
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n)
{
int end = m;
int start = 0;
for( int i = 0; i < nums2.size(); ++i )
{
while (nums1[start] <= nums2[i] && start < end )
start++;
for (int k = end; k >= start; --k)
{
nums1[k] = nums1[k - 1];
}
nums1[start] = nums2[i];
end++;
}
}
};
643. 子数组最大平均数 I
给定 n
个整数,找出平均数最大且长度为 k
的连续子数组,并输出该最大平均数。
示例 1:
输入: [1,12,-5,-6,50,3], k = 4
输出: 12.75
解释: 最大平均数 (12-5-6+50)/4 = 51/4 = 12.75
注意:
- 1 <=
k
<=n
<= 30,000。 - 所给数据范围 [-10,000,10,000]。
class Solution {
public:
double findMaxAverage(vector<int>& nums, int k) {
vector<int> nums1;
for(int i = 0; i<nums.size()-k; i++)
{
int count = 0;
for(int j = i; j <= j+k-1 ; j++)
count += nums[j];
int average = count/k;
nums1.push_back(average);
}
int maxPosition = max_element(nums1.begin(),nums1.end()) - nums1.begin();
return nums1[maxPosition];
}
};
485. 最大连续1的个数
给定一个二进制数组, 计算其中最大连续1的个数。
示例 1:
输入: [1,1,0,1,1,1]
输出: 3
解释: 开头的两位和最后的三位都是连续1,所以最大连续1的个数是 3.
注意:
- 输入的数组只包含
0
和1
。 - 输入数组的长度是正整数,且不超过 10,000。
class Solution {
public:
int findMaxConsecutiveOnes(vector<int>& nums) {
int count = 0;
vector<int> nums1;
for(int i = 0; i<nums.size(); i++)
{
if(nums[i] == 1)
count++;
if(nums[i] != 1 && count !=0)
{
nums1.push_back(count);
count = 0;
}
}
int maxValue = *max_element(nums1.begin(),nums1.end());
return maxValue;
}
};
169. 求众数
给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋
的元素。
你可以假设数组是非空的,并且给定的数组总是存在众数。
示例 1:
输入: [3,2,3]
输出: 3
示例 2:
输入: [2,2,1,1,1,2,2]
输出: 2
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(),nums.end());
int count = 1;
int max_count = 0;
int val = 0;
if(nums.size() == 1)
return nums[0];
for(int i = 0; i<nums.size(); i++)
{
if(nums[i] == nums[i+1])
{
count++;
if(max_count<count)
{
max_count = count;
val = nums[i];
}
}
if(nums[i] != nums[i+1])
count = 1;
}
return val;
}
};
674. 最长连续递增序列
给定一个未经排序的整数数组,找到最长且连续的的递增序列。
示例 1:
输入: [1,3,5,4,7]
输出: 3
解释: 最长连续递增序列是 [1,3,5], 长度为3。
尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为5和7在原数组里被4隔开。
示例 2:
输入: [2,2,2,2,2]
输出: 1
解释: 最长连续递增序列是 [2], 长度为1。
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
int count = 1;
int max_count = 0;
if(nums.size() == 1)
return 1;
if(nums.empty())
return 0;
for(int i = 0; i<nums.size()-1; i++)
{
if(nums[i] < nums[i+1])
count++;
if(max_count < count)
max_count = count;
if(nums[i] >= nums[i+1])
count = 1;
}
return max_count;
}
};
747. 至少是其他数字两倍的最大数
在一个给定的数组nums
中,总是存在一个最大元素 。
查找数组中的最大元素是否至少是数组中每个其他数字的两倍。
如果是,则返回最大元素的索引,否则返回-1。
示例 1:
输入: nums = [3, 6, 1, 0]
输出: 1
解释: 6是最大的整数, 对于数组中的其他整数,
6大于数组中其他元素的两倍。6的索引是1, 所以我们返回1.
示例 2:
输入: nums = [1, 2, 3, 4]
输出: -1
解释: 4没有超过3的两倍大, 所以我们返回 -1.
class Solution {
public:
int dominantIndex(vector<int>& nums) {
int maxPosition = max_element(nums.begin(),nums.end()) - nums.begin();
int maxvalue = nums[maxPosition];
int count = 0;
for(int i = 0; i<nums.size(); i++)
if(maxvalue >= 2*nums[i])
count++;
if(count == nums.size()-1)
return maxPosition;
else return -1;
}
};
532. 数组中的K-diff数对
给定一个整数数组和一个整数 k, 你需要在数组里找到不同的 k-diff 数对。这里将 k-diff 数对定义为一个整数对 (i, j), 其中 i 和 j 都是数组中的数字,且两数之差的绝对值是 k.
示例 1:
输入: [3, 1, 4, 1, 5], k = 2
输出: 2
解释: 数组中有两个 2-diff 数对, (1, 3) 和 (3, 5)。
尽管数组中有两个1,但我们只应返回不同的数对的数量。
示例 2:
输入:[1, 2, 3, 4, 5], k = 1
输出: 4
解释: 数组中有四个 1-diff 数对, (1, 2), (2, 3), (3, 4) 和 (4, 5)。
示例 3:
输入: [1, 3, 1, 5, 4], k = 0
输出: 1
解释: 数组中只有一个 0-diff 数对,(1, 1)。
注意:
- 数对 (i, j) 和数对 (j, i) 被算作同一数对。
- 数组的长度不超过10,000。
- 所有输入的整数的范围在 [-1e7, 1e7]。
class Solution {
public:
int findPairs(vector<int>& nums, int k) {
if(nums.size()==0||k<0){
return 0;
}
map<int,int> m ;
set<int> s;
int count = 0;
for(int i=0;i<nums.size();i++){
m[nums[i]]++;
}
for(int i=0;i<nums.size();i++){
if(k==0){
{
if(m[nums[i]]>=2){
s.insert(nums[i]);
}
count = s.size();
}
}else{
if(m[nums[i]+k]>0){
s.insert(nums[i]);
}
count = s.size();
}
}
return count;
}
};
561. 数组拆分 I
给定长度为 2n 的数组, 你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), ..., (an, bn) ,使得从1 到 n 的 min(ai, bi) 总和最大。
示例 1:
输入: [1,4,3,2]
输出: 4
解释: n 等于 2, 最大总和为 4 = min(1, 2) + min(3, 4).
提示:
- n 是正整数,范围在 [1, 10000].
- 数组中的元素范围在 [-10000, 10000].
class Solution {
public:
int arrayPairSum(vector<int>& nums) {
sort(nums.begin(),nums.end());
int sum =0;
for(int i = 0; i<nums.size()-1; i=i+2)
sum += nums[i];
return sum;
}
};
167. 两数之和 II - 输入有序数组
给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。
函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
说明:
- 返回的下标值(index1 和 index2)不是从零开始的。
- 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:
输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
class Solution {
public:
vector<int> twoSum(vector<int> &nums,int target){
unordered_map<int,int>mapping;
vector<int> a;
for(int i=0;i<nums.size();i++)
mapping[nums[i]]=i;
for(int i=0;i<nums.size();i++)
{
unsigned int result=target-nums[i];
if(mapping.find(result)!=mapping.end()&&mapping[result]>i)
{ a.push_back(i+1);
a.push_back(mapping[result]+1);
}
}
return a;
}
};
112. 删除排序链表中的重复元素
描述
给定一个排序链表,删除所有重复的元素每个元素只留下一个。
您在真实的面试中是否遇到过这个题? 是
样例
给出 1->1->2->null
,返回 1->2->null
给出 1->1->2->3->3->null
,返回 1->2->3->null
class Solution {
public:
/**
* @param head: head is the head of the linked list
* @return: head of linked list
*/
ListNode * deleteDuplicates(ListNode * head) {
// write your code here
if(!head || !head ->next) return head;
ListNode *cur = head -> next;
ListNode *pre = head;
while(cur)
{
if(cur -> val == pre ->val)
{
cur = cur-> next;
pre -> next = cur;
}
if(cur -> val != pre ->val)
{
cur = cur -> next;
pre = pre -> next;
}
}
return head;
}
};