示例 1:
输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] ==
9 ,返回 [0, 1] 。
双指针法
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
//先排序nums,
//再找到nums[0]下和大于target的最小end,start为0
//重复上述过程,在start和end之间寻找并更新start&end
vector<int> ans;
vector<int> temp(nums);
sort(temp.begin(),temp.end());
int e=temp.size()-1;
int i=0;
while(i<e && temp[i]+temp[e]!=target)
{
if(temp[i]+temp[e]>target)
e--;
else if(temp[i]+temp[e]<target)
i++;
}
if(temp[i]+temp[e]==target && i<e){
int j=0;
while(j<nums.size()){
if(nums[j]==temp[i] ||nums[j]==temp[e])
ans.push_back(j);
j++;
}
return ans;
}
return ans;
}
};
注意无序表用法
https://blog.csdn.net/qq_42147816/article/details/104452663#t50
//将所有元素放入查找表,之后对于每一个元素 a,查找 target - a 是否存在
//使用了无序表
class Solution
{
public:
vector<int> twoSum(vector<int>& nums, int target)
{
unordered_map<int,int> um;
vector<int> res;
for (int i = 0; i < nums.size(); ++i)
{
// 如果能在um中找到值为target-nums[i]的元素
if (um.find(target-nums[i])!=um.end())
{
res.push_back(i);
res.push_back(um[target-nums[i]]);
return res;
}
// 找不到就继续从num读一个数进去
um[nums[i]] = i;
}
return res;
}
};
//链接:https://leetcode-cn.com/problems/two-sum/solution/cjie-fa-su-du-ji-bai-98-by-zhu-que-3-mvdh/
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int cnt=0;
int ans=1;
int n=nums.size();
if(n==0) return 0;
for(int i=1;i<n;i++){
if(nums[i]==nums[i-1])
cnt++;
else
{
nums[i-cnt]=nums[i];
ans++;
}
}
return ans;
}
};
需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int cnt=0;
int step=0;
int n=nums.size();
for(int i=0;i<n;i++){
if(nums[i]==val)
step++;
else
nums[i-step]=nums[i];
}
return n-step;
}
};
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int i=0;
int n=nums.size();
while (i < n) {
if (nums[i] == val) {
nums[i] = nums[n - 1];
// reduce array size by one
n--;
// 注意i没有增加
} else {
i++;
}
}
return n;
}
};
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int size = nums.size();
if (size == 0) {
return 0;
}
int left = 0;
// 因为有可能数组的最后一个元素的位置的下一个是我们要找的,故右边界是 len
int right = size;
while (left < right) {
int mid = left + (right - left) / 2;
// 小于 target 的元素一定不是解
if (nums[mid] < target)
// 下一轮搜索的区间是 [mid + 1, right]
left = mid + 1;
else
right = mid;
}
return left;
}
};
// https://leetcode-cn.com/problems/maximum-subarray/solution/xiang-xi-jie-du-dong-tai-gui-hua-de-shi-xian-yi-li/
class Solution {
public:
// dp法
int maxSubArray(vector<int>& nums) {
//类似寻找最大最小值的题目,初始值一定要定义成理论上的最小最大值
int result = INT_MIN;
int numsSize = int(nums.size());
//dp[i]表示nums中以nums[i]结尾的最大子序和
vector<int> dp(numsSize);
dp[0] = nums[0];
result = dp[0];
for (int i = 1; i < numsSize; i++)
{
dp[i] = max(dp[i - 1] + nums[i], nums[i]);
// 时时更新result
result = max(result, dp[i]);
}
return result;
// https://leetcode-cn.com/problems/maximum-subarray/solution/zui-da-zi-xu-he-cshi-xian-si-chong-jie-fa-bao-li-f/
}
};
按部就班的写,非常冗长
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
int n=digits.size();
if(digits[n-1]!=9) {
digits[n-1]+=1;
return digits;
}
int i=n-1;
int temp=digits[i];
while(i>0 && temp==9){
digits[i] = 0;
temp=digits[i-1];
digits[i-1]+=1;
i--;
}
if(i==0 && temp==9)
{
//这个赋值只是为了包括9这个例子
digits[i] = 0;
digits.insert(digits.begin(),1);
}
return digits;
}
};
非常简练
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
int len = digits.size();
for(int i = len - 1; i >= 0; i--) {
digits[i]++; // 最初的+1 或者进位
// 简练!
digits[i] %= 10;
// 129或者123这样的数字在这里退出
if(digits[i]!=0)
return digits;
}
//到这里才退出说明是999这样的数字
digits.insert(digits.begin(),1);
return digits;
// https://leetcode-cn.com/problems/plus-one/solution/hua-jie-suan-fa-66-jia-yi-by-guanpengchn/
}
};
//官方解答非常nice
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
// 三指针 指针一p1:nums1有效元素尾部;指针二p2:nums2尾部;
//指针三p3:最终数组尾部
// 1.when p1>=0时, compare nums[p1] with nums[p2]
// 1.1 if nums[p1] is larger,put nums[p1] into p3 then p1--,p3--
// 1.2 if nums[p2]>=nums[p1],put nums[p2] into p3 then p2--,p3--
// 2.when p1<0, put nums[p2] into p3 then p2--,p3--
// End when: p2<0
// 注意!p3的初始值是m+n-1,覆盖nums1无所谓!
int p1=m-1,p2=n-1,p3=m+n-1;
while(p2 >= 0){
if(p1 >= 0 && nums1[p1] > nums2[p2]){
nums1[p3--] = nums1[p1--];
} else {
nums1[p3--] = nums2[p2--];
}
}
}
};
class Solution {
public:
vector<vector<int>> generate(int numRows) {
// 必须带空格
vector<vector<int> > ans(numRows);//设置行数
int n=0;
for(int i=0;i<numRows;i++){
// 注意二维数组的写法,这里resize每一行的大小
ans[i].resize(i + 1);
ans[i][0]=1;
ans[i][i]=1;
for(int j=1;j<i;j++)
ans[i][j]=ans[i-1][j-1]+ans[i-1][j];
}
return ans;
}
};
DP:dp[i][0] 下标为 i 这天结束的时候,不持股,手上拥有的现金数
dp[i][1] 下标为 i 这天结束的时候,持股,手上拥有的现金数
class Solution {
public:
// dp
int maxProfit(vector<int>& prices) {
int len = prices.size();
// 特殊判断
if (len < 2)
return 0;
int dp[len][2];
// dp[i][0] 下标为 i 这天结束的时候,不持股,手上拥有的现金数
// dp[i][1] 下标为 i 这天结束的时候,持股,手上拥有的现金数
// 初始化:不持股显然为 0,持股就需要减去第 1 天(下标为 0)的股价
dp[0][0] = 0;
dp[0][1] = -prices[0];
// 从第 2 天开始遍历
for (int i = 1; i < len; i++) {
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
dp[i][1] = max(dp[i - 1][1], -prices[i]);
}
return dp[len-1][0];
//https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/solution/bao-li-mei-ju-dong-tai-gui-hua-chai-fen-si-xiang-b/
}
};
贪心算法:每天都买,每天都卖,亏则不买,赚就买。
// 每天都买&每天都卖,亏则不买,赚就买。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int profit = 0;
for (int i = 1; i < prices.size(); i++) {
int tmp = prices[i] - prices[i - 1];
if (tmp > 0) profit += tmp;
}
return profit;
}};
// https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/solution/best-time-to-buy-and-sell-stock-ii-zhuan-hua-fa-ji/
DP,但是很显然没有方法二nice
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
int dp[n][2];
dp[0][0] = 0, dp[0][1] = -prices[0];
for (int i = 1; i < n; ++i) {
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
}
return dp[n - 1][0];
}
};
//https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/solution/mai-mai-gu-piao-de-zui-jia-shi-ji-ii-by-leetcode-s/
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
vector<int> ans;
int i=0,j=numbers.size()-1;
while(i!=j){
if(numbers[i]+numbers[j]==target){
ans.push_back(i+1);
ans.push_back(j+1);
break;
}
if(numbers[i]+numbers[j]<target)
i++;
if(numbers[i]+numbers[j]>target)
j--;
}
return ans;
}
};
按部就班的方法
class Solution {
public:
int majorityElement(vector<int>& nums) {
int n=nums.size();
int major=nums[0];
int cnt=1;
if(n!=1)
{for(int i=1;i<n;i++){
if(nums[i]==major)
cnt++;
else if(nums[i]!=major && cnt==0){
cnt=1;
major=nums[i];
}
else if(nums[i]!=major && cnt!=0){
cnt--;
}
}
}
return major;
}
};
hash+打擂台避免最后遍历,不断与cnt比较并且更新
class Solution {
public:
int majorityElement(vector<int>& nums) {
unordered_map<int, int> counts;
int majority = 0, cnt = 0;
for (int num: nums) {
++counts[num];
//打擂台避免最后遍历
if (counts[num] > cnt) {
majority = num;
cnt = counts[num];
}
}
return majority;
}
};
//https://leetcode-cn.com/problems/majority-element/solution/duo-shu-yuan-su-by-leetcode-solution/
unordered_map
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
unordered_map<int,int> st;
int n=nums.size();
for(int i=0;i<n;i++){
if((++st[nums[i]]) > 1)
return true;
}
return false;
}
};
unordered_set
for (int x: nums)
的写法class Solution {
public:
// ²»ÓÃhashÓÃset
bool containsDuplicate(vector<int>& nums) {
unordered_set<int> s;
for (int x: nums) {
if (s.find(x) != s.end()) {
return true;
}
s.insert(x);
}
return false;
}
};
//https://leetcode-cn.com/problems/contains-duplicate/solution/cun-zai-zhong-fu-yuan-su-by-leetcode-sol-iedd/
class Solution {
public:
bool containsNearbyDuplicate(vector<int>& nums, int k) {
unordered_map<int,int> st;
int n=nums.size();
for(int i=0;i<n;i++){
if(st.find(nums[i])!=st.end()){
int temp=i - st[nums[i]];
if(temp<=k) return true;
else st[nums[i]]=i;
}
else st[nums[i]] = i;
}
return false;
}
};
class Solution {
public:
vector<string> summaryRanges(vector<int>& nums) {
vector<string> ret;
int i = 0;
int n = nums.size();
while (i < n) {
int low = i;
i++;
while (i < n && nums[i] == nums[i - 1] + 1) {
i++;
}
int high = i - 1;
string temp = to_string(nums[low]);
if (low < high) {
temp.append("->");
temp.append(to_string(nums[high]));
}
// move后值被转移,temp为空
ret.push_back(move(temp));
}
return ret;
// https://leetcode-cn.com/problems/summary-ranges/solution/hui-zong-qu-jian-by-leetcode-solution-6zrs/
}
};
排序or哈希,时复or空复高
//方法一:排序
class Solution {
public:
int missingNumber(vector<int>& nums) {
sort(nums.begin(),nums.end());
int i;
for(i=0;i<nums.size();i++){
if(nums[i]!=i)
break;
}
return i;
}
};
//方法二:哈希法
class Solution {
public:
int missingNumber(vector<int>& nums) {
map<int,int> mp;
int i;
int n=nums.size();
for(i=0;i<n;i++){
mp[nums[i]]=-1;
}
for(i=0;i<=n;i++){
if(mp[i]!=-1) break;
}
return i;
}
};
class Solution {
// 位运算方法
//按位^异或运算符,按位~反运算符
public:
int missingNumber(vector<int>& nums) {
int res = nums.size();
for(int i = 0; i < nums.size(); ++i)
res = res ^ i ^ nums[i]; // a^b^b = a;
return res ;
}
};
// https://leetcode-cn.com/problems/missing-number/solution/c-z-by-zrita-14/
class Solution {
// 数学方法:求出 [0..n]的和,减去数组中所有数的和,就得到了缺失的数字
public:
int missingNumber(vector<int>& nums) {
int sum = 0, n = nums.size();
for(int n : nums)
sum += n;
return (n * (n+1)) / 2 - sum;
}
};
//https://leetcode-cn.com/problems/missing-number/solution/c-z-by-zrita-14/
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int n=nums.size();
int i=0;
int cnt=0;
while(i<n){
if(nums[i]==0)
cnt++;
else if(nums[i]!=0)
nums[i-cnt]=nums[i];
i++;
}
i=i-cnt;
while(i<n){
nums[i]=0;
i++;
}
}
};
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
map<int,int> mp;
vector<int> ans;
int n=nums.size();
for(int i=0;i<n;i++){
mp[nums[i]]=-1;
}
for(int i=1;i<=n;i++){
if(mp[i]!=-1)
ans.push_back(i); // 换成emplace_back后时间从228---204
}
return ans;
}
};
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
int n=nums.size();
vector<int> ans;
// 记住声明方式
//int *a = new int[m];
//memset( &a, 0, sizeof(a) );
//注意第一个参数是指针类型,a不是指针变量,要加&
//memset按字节赋值,int为4字节
for(int i=0;i<n;i++){
if(nums[abs(nums[i])-1] > 0)
nums[abs(nums[i])-1]=-nums[abs(nums[i])-1];
}
for(int i=0;i<n;i++){
if(nums[i]>0)
ans.push_back(i+1);
}
return ans;
}
};
class Solution {
public:
int findMaxConsecutiveOnes(vector<int>& nums) {
int maxcnt=0;
int cnt=0;
int n=nums.size();
for(int i=0;i<n;i++){
if(nums[i]==1) cnt++;
else if(nums[i]==0 && cnt>maxcnt) {
maxcnt=cnt;
cnt=0;
}
else cnt=0;
}
// 最后一定再比较一次!
return cnt>maxcnt?cnt:maxcnt;
}
};
递归
class Solution {
public:
int fib(int n) {
if(n==0) return 0;
if(n==1) return 1;
else return fib(n-1) + fib(n-2);
}
};
class Solution {
public:
// 滚动数组的方法
int fib(int n) {
if (n < 2) {
return n;
}
// 只需要保留相邻2个状态即可
int p = 0, q = 0, r = 1;
for (int i = 2; i <= n; ++i) {
p = q;
q = r;
r = p + q;
}
return r;
}
};
// https://leetcode-cn.com/problems/fibonacci-number/solution/fei-bo-na-qi-shu-by-leetcode-solution-o4ze/
class Solution {
public:
int arrayPairSum(vector<int>& nums) {
sort(nums.begin(),nums.end());
int ans=0;
for(int i=0;i<nums.size();i+=2){
ans+=nums[i];
}
return ans;
}
};
class Solution {
public:
vector<vector<int>> matrixReshape(vector<vector<int>>& nums, int r, int c) {
vector<vector<int> > res(r, vector<int>(c, 0));
int row = nums.size();
int col = nums[0].size();
if ( row == 0 || row * col != r * c ) return nums;
int curRow = 0, curCol = 0;
for ( int i = 0; i < row; ++i ) {
for ( int j = 0; j < col; ++j ) {
res[curRow][curCol] = nums[i][j];
++curCol;
// 当前行满了, 变成下一行
if ( curCol == c ) {
curCol = 0;
++curRow;
}
}
}
return res;
}
};
思路清晰的跳格子法
class Solution {
public:
bool canPlaceFlowers(vector<int>& flowerbed, int n) {
int t = flowerbed.size();
if(t==0) return true;
int i=0;
while(i < t && n > 0) {
if (flowerbed[i] == 1) {
i += 2;
} else if (i == t - 1 || flowerbed[i + 1] == 0) {
n--;
i += 2;
} else {
i += 3;
}
}
return n <= 0;
// https://leetcode-cn.com/problems/can-place-flowers/solution/fei-chang-jian-dan-de-tiao-ge-zi-jie-fa-nhzwc/
}
};
sort+讨论情况做
class Solution {
public:
int maximumProduct(vector<int>& nums) {
int n=nums.size();
if(n==3) return nums[0]*nums[1]*nums[2];
sort(nums.begin(),nums.end());
int i=0,max;
while(i < n && nums[i] <= 0)
i++;
// 全为正数
if(i == 0) return nums[n-1]*nums[n-2]*nums[n-3];
// 全为负数或有0
if(i == n) return nums[n-1]*nums[n-2]*nums[n-3];
// 有负数,第一个正数下标为i;
else if(i<n){
//1正2负 > 3正
max = nums[n-1]*nums[0]*nums[1] > nums[n-1]*nums[n-2]*nums[n-3]? nums[n-1]*nums[0]*nums[1]: nums[n-1]*nums[n-2]*nums[n-3];
}
return max;
}
};
class Solution {
public:
int maximumProduct(vector<int>& nums) {
sort(nums.begin(), nums.end());
int n = nums.size();
return max(nums[0] * nums[1] * nums[n - 1], nums[n - 3] * nums[n - 2] * nums[n - 1]);
}
};
// https://leetcode-cn.com/problems/maximum-product-of-three-numbers/solution/san-ge-shu-de-zui-da-cheng-ji-by-leetcod-t9sb/
class Solution {
public:
int maximumProduct(vector<int>& nums) {
// 最小的和第二小的
int min1 = INT_MAX, min2 = INT_MAX;
// 最大的、第二大的和第三大的
int max1 = INT_MIN, max2 = INT_MIN, max3 = INT_MIN;
for (int x: nums) {
if (x < min1) {
min2 = min1;
min1 = x;
} else if (x < min2)
min2 = x;
if (x > max1) {
max3 = max2;
max2 = max1;
max1 = x;
} else if (x > max2) {
max3 = max2;
max2 = x;
} else if (x > max3)
max3 = x;
}
return max(min1 * min2 * max1, max1 * max2 * max3);
}
};
// https://leetcode-cn.com/problems/maximum-product-of-three-numbers/solution/san-ge-shu-de-zui-da-cheng-ji-by-leetcod-t9sb/
大小为k的滑动窗口:窗口向前滑动时,每向前滑动一位,就减去上一个子数组的首元素,加上新加进来子数组的新元素
class Solution {
public:
double findMaxAverage(vector<int>& nums, int k) {
double sum_k = 0;
for (int i = 0; i < k; i++)
sum_k += nums[i];
double max_sum_k = sum_k;
for (int i = k; i < nums.size(); i++) {
sum_k = sum_k - nums[i - k] + nums[i];
max_sum_k = max(max_sum_k, sum_k);
}
return max_sum_k / k;
}
// https://leetcode-cn.com/problems/maximum-average-subarray-i/solution/chua-dong-chuang-kou-jie-jue-lian-xu-zi-shu-zu-wen/
};
最多 改变 1 个元素的情况下,该数组能否变成一个非递减数列。
https://leetcode-cn.com/problems/non-decreasing-array/
方法一:
就暴力···试错了好多用例,最后结果不错。时复99.8%
class Solution {
public:
bool checkPossibility(vector<int>& nums) {
int i=0,j=1,n,k;
n = nums.size();
while(j < n && nums[i] <= nums[j]){
i++; j++;
}
// 本身是非递减的,或者最后一个元素递减了(此时当然可以修改)
if(j >= n-1) return true;
// 只有第一个元素不符合的话也OK
for(k=1;k<n-1 && nums[k] <= nums[k+1];k++);
if(k >= n-1) return true;
// 普通情况:
// 出现一个元素nums[i]使得nums[i] > nums[j]
// 判断它后面的是不是都是非递减
i = j+1; j = j+2;
// 先判断i的左右元素是否有非递减关系
// nums[i-1]或nums[i-2]如果有一个有问题
// 便不可能成为阶梯式的数组
if(i >= 2 && nums[i-2] <= nums[i]){
// 再判断i后面的是不是非递减
while(j < n && nums[i] <= nums[j]){
i++; j++;
}
if(j>=n) return true;
}
else if(i >=3 && nums[i-3] <= nums[i-1]){
i=i-1;j=j-1;
while(j < n && nums[i] <= nums[j]){
i++; j++;
}
if(j>=n) return true;
}
return false;
}
};
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
int Max=1;
int n=nums.size();
if(n == 0) return 0;
for(int i=1;i<n;i++){
int len=1;
while(i < n && nums[i-1] < nums[i]){
len++;
i++;
}
// Max = Max
if(Max < len) Max = len;
}
return Max;
}
};
class Solution {
public:
int findShortestSubArray(vector<int>& nums) {
map<int ,int> mp;
map<int ,int> vis;
int n=nums.size();
int cnt=0;
int i,ans=n;
for(i=0; i < n; i++){
mp[nums[i]]++;
if(mp[nums[i]] > cnt)
cnt= mp[nums[i]];
}
for(i=0; i < n; i++){
if(mp[nums[i]] == cnt && !vis[nums[i]]){
vis[nums[i]] = 1;
int temp = 1;
int j = i + 1;
while(j < n && temp < cnt) {
if(nums[j] == nums[i])
temp++; // 子序列中出现的频数
j++;
}
if(temp == cnt && (j-i) < ans)
ans = j-i;
}
}
return ans;
}
};
无技巧,想明白了怎么监测的就行
class Solution {
public:
bool isOneBitCharacter(vector<int>& bits) {
int n=bits.size();
// if(n > 1 && bits[n-2] == 0) return true;
int i=0;
while(i < n - 1){
if(bits[i] == 0)
i+=1;
else
i+=2;
}
//退出的时候看最后跳的步长是1还是2:
//i==bits.length-1 说明最后跳的步长是1,说明是1bit 0结尾
//i==bits.length 说明最后跳的步长是2,说明不是1bit 0 结尾
return i == n-1;
}
};
class Solution {
public:
int pivotIndex(vector<int>& nums) {
int dpl[10000];
int dpr[10000];
int n = nums.size();
dpl[0] = 0;
dpr[n-1] = 0;
for(int i = 1; i < n; i++){
dpl[i] = dpl[i-1] + nums[i-1];
dpr[n-i-1] = dpr[n-i] +nums[n-i];
}
for(int i=0; i < n;i++){
if(dpl[i] == dpr[i])
return i;
}
return -1;
}
};
class Solution {
public:
int pivotIndex(vector<int> &nums) {
//int total = accumulate(nums.begin(), nums.end(), 0);
int sum = 0;
int total= 0;
for (int i = 0; i < nums.size(); ++i){
total+=nums[i];
}
for (int i = 0; i < nums.size(); ++i) {
if (2 * sum + nums[i] == total) {
return i;
}
sum += nums[i];
}
return -1;
}
};
// https://leetcode-cn.com/problems/find-pivot-index/solution/xun-zhao-shu-zu-de-zhong-xin-suo-yin-by-gzjle/
class Solution {
public:
int dominantIndex(vector<int>& nums) {
int pos=0;
if(nums.size() == 1) return pos;
int max=nums[0],temp=-1;
for(int i=0; i < nums.size(); i++){
if(nums[i] <= temp || nums[i] == max)
continue;
else if(nums[i] > max) {
temp = max;
max = nums[i];
pos = i;
}
else
temp = nums[i];
}
if(temp && (max / temp) >= 2 || temp == 0)
return pos;
else return -1;
}
};
伤害极强,只需要和它zuo的元素比较久可以了
class Solution {
public:
bool isToeplitzMatrix(vector<vector<int>>& matrix) {
if(matrix.size()==1 || matrix[0].size()==1) return true;
for(int i=1; i<matrix.size(); i++){
for(int j=1; j<matrix[0].size(); j++){
if(matrix[i][j]!=matrix[i-1][j-1]) return false;
}
}
return true;
}
// https://leetcode-cn.com/problems/toeplitz-matrix/solution/c-jian-dan-ti-jie-by-shi-fen-fang-qi-zhong-5/
};
class Solution {
public:
vector<vector<int>> largeGroupPositions(string s) {
int n=s.length();
vector<vector<int>> ans;
for(int i=0; i<n; i++){
char c = s[i];
int j = i;
while(j+1 < n && c == s[j+1]){
j++;
c = s[j];
}
if(j-i > 1){
vector<int> temp;
temp.push_back(i);
temp.push_back(j);
ans.push_back(move(temp));
}
i = j;
}
return ans;
}
};
class Solution {
public:
vector<vector<int>> flipAndInvertImage(vector<vector<int>>& A) {
int n = A.size();
for(int j = 0; j < n; j++ ){
for(int i = 0; i < (n+1)/2; i++){
int temp = A[j][n-1-i] ^ 1;
A[j][n-1-i] = A[j][i] ^ 1;
A[j][i] = temp;
}
}
return A;
}
};
class Solution {
public:
vector > transpose(vector>& A) {
vector > v(A[0].size(),vector(A.size(),0));
for(int i=0;i
class Solution {
public:
vector<int> fairCandySwap(vector<int>& A, vector<int>& B) {
int sumA = accumulate(A.begin(), A.end(), 0);
int sumB = accumulate(B.begin(), B.end(), 0);
int delta = (sumA - sumB) / 2;
unordered_set<int> rec(A.begin(), A.end());
vector<int> ans;
for (auto& y : B) {
int x = y + delta;
if (rec.count(x)) {
ans = vector<int>{x, y};
break;
}
}
return ans;
}
};
// https://leetcode-cn.com/problems/fair-candy-swap/solution/gong-ping-de-tang-guo-jiao-huan-by-leetc-tlam/
class Solution {
public:
vector<int> sortArrayByParity(vector<int>& A) {
int i=0,j=0;
int n = A.size();
// i指向偶
while(i < n && A[i] % 2 != 0)
i++;
// j指向奇
while(j < n && A[j] % 2 == 0)
j++;
// 全奇或全偶
if(i == n || j == n) return A;
while(i < n && j < n){
// 偶在奇后面
if(i > j){
swap(A[i],A[j]);
// 移动i
i++;
while(i < n && A[i] % 2 != 0)
i++;
// 移动j
j++;
while(j < n && A[j] % 2 == 0)
j++;
}
// 奇在偶后面
else {
// 只移动i
i++;
while(i < n && A[i] % 2 != 0)
i++;
}
}
return A;
}
};
#include< algorithm>
class Solution {
// 可以添加在这里
int cnt[10000];
public:
bool hasGroupsSizeX(vector<int>& deck) {
for (auto x: deck)
cnt[x]++;
int g = cnt[0];
// gcd:#include< algorithm>
for (int i = 1; i < 10000; ++i) {
if (cnt[i]) {
g = gcd(g, cnt[i]);
}
}
return g >= 2;
}
};
// https://leetcode-cn.com/problems/x-of-a-kind-in-a-deck-of-cards/solution/qia-pai-fen-zu-by-leetcode-solution/
class Solution {
public:
vector<int> sortArrayByParityII(vector<int>& A) {
int i=1,j=0;
int n = A.size();
//i偶j奇
while(i < n && j < n){
// 搜寻在奇数位置上的偶数
while(i < n && A[i]%2 != 0 ){
i+=2;
}
// 搜寻在偶数位置上的奇数
while(j < n && A[j]%2 == 0 ){
j+=2;
}
if(i < n && j < n)
swap(A[i],A[j]);
}
return A;
}
};
class Solution {
public:
bool validMountainArray(vector<int>& arr) {
int n = arr.size();
int i = 0;
// 退出for时是山顶
while(i < n-1 && arr[i] < arr[i+1]){
i++;
}
if(i == n-1 || i == 0) return false;
i++;
while(i < n && arr[i-1] > arr[i])
i++;
if(i < n)
return false;
return true;
}
};
class Solution {
public:
vector<int> sumEvenAfterQueries(vector<int>& A, vector<vector<int>>& queries) {
vector<int> answer;
int sum = 0;
// 先求偶数和
for(int i = 0; i < A.size(); i++)
if(A[i]%2 == 0)
sum += A[i];
for(int i = 0; i < queries.size(); i++){
int val = queries[i][0];
int index = queries[i][1];
int temp = A[index];
A[index] += val;
// 如果改变的数是偶数
if(temp%2 == 0)
sum -= temp;
// 如果改变后的数是偶数
if(A[index]%2 == 0)
sum += A[index];
answer.emplace_back(sum);
}
return answer;
}
};
class Solution {
public:
// 简单直接的方法
vector<int> addToArrayForm(vector<int>& A, int K) {
// 注意一下反转A,或者从A.size()-1开始才是个位
reverse(A.begin(), A.end());
int c = 0;
for (int i = 0; (K != 0 || c != 0); i++) {
// 这种为A添加0的方法比讨论A和K的长度要好
if (i >= A.size()) {
A.push_back(0);
}
// 取A的末尾数字
int a = A[i];
// 取K的末尾数字
int b = K % 10;
// K移位
K /= 10;
int sum = a + b + c;
// 更新A[i]
A[i] = (sum % 10);
// 更新进位
c = sum / 10;
}
reverse(A.begin(), A.end());
return A;
}
};
// https://leetcode-cn.com/problems/add-to-array-form-of-integer/solution/add-to-array-by-ikaruga-tnbr/
class Solution {
public:
// 一个稍微复杂的方法
vector<int> addToArrayForm(vector<int>& A, int K) {
int i = A.size()-1;
// 直接把K加到A中,再取个位数
while(K > 0){
// A[i]+K,与实际上A[i]只保留个位数
A[i] += K;
// 此时K实际上是:进位的值 + K
K = A[i] / 10;
// A[i]只保留个位数
A[i--] %= 10;
// K长A短的情况
if(i < 0 && K > 0){
// 在开头插入0
A.insert(A.begin(),0);
// i指针放在开头
i = 0;
}
}
return A;
}
};
// https://leetcode-cn.com/problems/add-to-array-form-of-integer/solution/pythonc-san-chong-jie-fa-by-milomusiala-7wc5/
下棋,题意复杂,实现简单
https://leetcode-cn.com/problems/available-captures-for-rook/
方法一:直接暴力
class Solution {
public:
int numRookCaptures(vector>& board) {
int r = board.size();
int c = board[0].size();
int ri,rj;
int cnt = 0;
// 找车
for(int i = 0; i < r; i++)
for(int j = 0; j < c; j++)
if(board[i][j] == 'R'){
ri = i;
rj = j;
break;
}
//车向4个方向移动,判断停止条件
// 向东
for(int i = ri; i < r; i++)
{
if(board[i][rj] == 'B' )
break;
if(board[i][rj] == 'p'){
cnt++;
break;
}
}
// 向西
for(int i = ri; i >= 0; i--)
{
if(board[i][rj] == 'B' )
break;
if(board[i][rj] == 'p'){
cnt++;
break;
}
}
// 向北
for(int j = rj; j >= 0; j--)
{
if(board[ri][j] == 'B' )
break;
if(board[ri][j] == 'p'){
cnt++;
break;
}
}
// 向南
for(int j = rj; j < r; j++)
{
if(board[ri][j] == 'B' )
break;
if(board[ri][j] == 'p'){
cnt++;
break;
}
}
return cnt;
}
};
返回列表中的每个字符串中都显示的全部字符(包括重复字符)组成的列表
https://leetcode-cn.com/problems/find-common-characters/
class Solution {
public:
vector commonChars(vector& A) {
vector result;
if (A.size() == 0) return result;
int hash[26] = {0}; // 用来统计所有字符串里字符出现的最小频率
for (int i = 0; i < A[0].size(); i++) { // 用第一个字符串给hash初始化
// 注意字符到int转换的写法
hash[A[0][i] - 'a']++;
}
int hashOtherStr[26] = {0}; // 统计除第一个字符串外字符的出现频率
// 关键
for (int i = 1; i < A.size(); i++) {
memset(hashOtherStr, 0, 26 * sizeof(int));
for (int j = 0; j < A[i].size(); j++) {
hashOtherStr[A[i][j] - 'a']++;
}
// 更新hash,保证hash里统计26个字符在所有字符串里出现的最小次数
for (int k = 0; k < 26; k++) {
hash[k] = min(hash[k], hashOtherStr[k]);
}
}
// 将hash统计的字符次数,转成输出形式
for (int i = 0; i < 26; i++) {
while (hash[i] != 0) { // 注意这里是while,多个重复的字符
string s(1, i + 'a'); // char -> string
result.push_back(s);
hash[i]--;
}
}
return result;
}
};
// https://leetcode-cn.com/problems/find-common-characters/solution/1002-cha-zhao-chang-yong-zi-fu-ha-xi-fa-jing-dian-/
给你一个整数数组 A
,只有可以将其划分为三个和相等的非空部分时才返回 true
,否则返回 false
。
https://leetcode-cn.com/problems/partition-array-into-three-parts-with-equal-sum/
思路简单,找3次sum/3的和即可
// c++提速https://blog.csdn.net/weixin_43213056/article/details/100548067
static const auto _ = []()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
return nullptr;
}();
class Solution {
public:
bool canThreePartsEqualSum(vector& arr) {
int n = arr.size();
int i=1,j = n-2;
int sum = accumulate(arr.begin() , arr.end() , 0);
int sum1 = 0;
// 如果sum不能恰好分成3份
if(sum%3 != 0)
return false;
// 从前往后找sum/3
sum1 = arr[0];
while(i < n && sum1 != sum/3){
sum1 += arr[i];
i++;
}
if(i == n ) return false;
// 从后往前找sum/3
sum1 = arr[n-1];
while(j > i && sum1 != sum/3 ){
sum1 += arr[j];
j--;
}
if(i-1 == j) return false;
// 从i到j求sum1,与sum/3比较
sum1 = 0;
while(i <= j){
sum1 += arr[i];
i++;
}
if(sum1 == sum/3) return true;
else return false;
}
};
N_i
:从 A[0]
到 A[i]
的第 i
个子数组被解释为一个二进制数(从最高有效位到最低有效位)。一开始是溢出,后来倒数第二个用例超时,无解
class Solution {
public:
vector prefixesDivBy5(vector& A) {
vector answer;
int n = A.size();
vector tmp;
for(int i = 0; i < n; i++){
int N_i = 0;
// 确定第1位的值
if(A[i] == 1) tmp.emplace_back(1);
else tmp.emplace_back(0);
// 加到N_i上
N_i += tmp[i];
// 从第2位开始*2遍历
for(int j = i-1; j >= 0; j--){
tmp[j] = tmp[j]*2;
// 改进了,只取个位数。
tmp[j] %= 10;
N_i += tmp[j];
}
if(N_i%5 == 0) answer.emplace_back(true);
else answer.emplace_back(false);
}
return answer;
}
};
class Solution {
public:
vector prefixesDivBy5(vector& A) {
vector ans(A.size());
int num = 0;
for(int i = 0 ; i < A.size(); i ++){
// 左移一位,乘2,再加上新的末位
num = (num<<1) + A[i];
// 只保留最后一位,但实际上直接num %= 5也是可以的
// num %= 10;
// ans[i] = (num % 5 == 0);
num %= 5;
ans[i] = (num == 0);
}
return ans;
}
};
// https://leetcode-cn.com/problems/binary-prefix-divisible-by-5/solution/ji-bai-shuang-100zui-rong-yi-li-jie-de-s-0dba/
返回能让所有学生以 非递减 高度排列的最小必要移动人数(不是移动次数)。
https://leetcode-cn.com/problems/height-checker/
方法二:
关键不要想复杂····将输入的参数赋值给另外一个vector容器, 然后将该容器内的元素进行排序, 最后同heights进行对比, 统计在相同位上的数值不相同的元素个数总和.
class Solution {
public:
// 将输入的参数赋值给另外一个vector容器, 然后将该容器内的元素进行排序, 最后同heights进行对比, 统计在相同位上的数值不相同的元素个数总和.
int heightChecker(vector& heights) {
int size = heights.size();
vector vec(heights);
sort(vec.begin(), vec.end());
int i = 0;
int j = 0;
int count = 0;
for(i = 0, j = 0; i < size, j < size; i++, j++)
{
if(heights[i] != vec[j])
{
++count;
}
}
return count;
}
};
// https://leetcode-cn.com/problems/height-checker/solution/fen-xiang-jie-ti-si-lu-by-wilson1116/
将数组中出现的每个零都复写一遍,并将其余的元素向右平移。请不要在超过该数组长度的位置写入元素。
就地进行上述修改
方法一失败是因为迭代器失效:
https://www.cnblogs.com/fnlingnzb-learner/p/9300073.html
对于序列式容器,比如vector,删除或添加当前的iterator会使后面所有元素的iterator都失效。这是因为顺序容器内存是连续分配(分配一个数组作为内存)。
当删除一个元素后,其他数据的地址发生了变化,之前获取的迭代器根据原有的信息就访问不到正确的数据。
插入时,因为size()==capacity(),故插入元素后,vector被重新分配内存。可以看下面两个
https://www.jianshu.com/p/6f08b1d4271a
https://www.zhihu.com/question/37352989
获取insert或者erase返回的迭代器,以便用重新获取新的有效的迭代器进行正确的操作:
iter=vec.insert(iter);
iter=vec.erase(iter);
在添加、删除、修改元素时,尽量直接使用begin()和end(),或者使用insert()和erase()更新相应的迭代器,避免使用迭代器的中间量。
vector vi;
//i保存的是vi的迭代器,有时操作后(如添加元素,删除元素)不确定i是否有效
auto i=vi.begin()+n;
vi.erase(i);
//尽量直接使用begin()和end(),避免使用中间量i
vi.erase(vi.begin()+n);
//下面的表达式更好,因为它会自动更新i
i=vi.erase(i);
方法一代码不贴了
两次遍历,提前预留空间
class Solution {
public:
// 两次遍历,提前预留空间
void duplicateZeros(vector& arr) {
int len = arr.size();
int i = 0, count = 0;
/*第一次遍历,计算有效位置i,统计能装下的有效数据个数i + count*/
for(;i < len; i++) {
if (arr[i] == 0) count++;
if ((i + count) >= len - 1) break;
}
/*特殊判断,能装下的有效数据个数为i + count*/
if ((count + i) > len - 1) {
arr[len-- - 1] = arr[i--];
}
/*从i开始倒着填充数据*/
int j = len - 1;
while (j > i) {
if (arr[i] == 0) {
arr[j] = 0;
arr[--j] = 0;
} else {
arr[j] = arr[i];
}
i--;
j--;
}
}
};
// https://leetcode-cn.com/problems/duplicate-zeros/solution/fu-xie-ling-bao-li-guan-fang-shuang-zhi-zhen-by-hu/
arr1
中的元素进行排序,使 arr1
中项的相对顺序和 arr2
中的相对顺序相同。未在 arr2
中出现过的元素需要按照升序放在 arr1
的末尾。class Solution {
public:
// 计数排序
vector relativeSortArray(vector& arr1, vector& arr2) {
// 找出数组 arr1中的最大值upper,使用长度为upper+1的数组
int upper = *max_element(arr1.begin(), arr1.end());
// frequency记录每一个元素在arr1中出现的次数
vector frequency(upper + 1);
for (int x: arr1) {
++frequency[x];
}
vector ans;
// 我们将 frequency[x]个数值加入答案中,并将 frequency[x]清零。
for (int x: arr2) {
for (int i = 0; i < frequency[x]; ++i) {
ans.emplace_back(x);
}
frequency[x] = 0;
}
// 从0开始递增直到upper
for (int x = 0; x <= upper; ++x) {
// 有几次输出几遍
for (int i = 0; i < frequency[x]; ++i) {
ans.emplace_back(x);
}
}
return ans;
}
};
// https://leetcode-cn.com/problems/relative-sort-array/solution/shu-zu-de-xiang-dui-pai-xu-by-leetcode-solution/
0
度或 180
度得到另一张多米诺骨牌,我们就认为这两张牌是等价的。调整顺序并将每一个二元对拼接成一个两位的正整数val
class Solution {
public:
// 计数排序
int numEquivDominoPairs(vector>& dominoes) {
vector num(100);
int ret = 0;
for (auto& it : dominoes) {
//调整顺序并将每一个二元对拼接成一个两位的正整数val
int val = it[0] < it[1] ? it[0] * 10 + it[1] : it[1] * 10 + it[0];
// 计数,第一次是0
ret += num[val];
num[val]++;
}
return ret;
}
};
// ttps://leetcode-cn.com/problems/number-of-equivalent-domino-pairs/solution/deng-jie-duo-mi-nuo-gu-pai-dui-de-shu-li-yjlz/
chars
中的『字母』(字符)拼写出 words
中的某个『单词』(字符串),那么我们就认为你掌握了这个单词。能用int数组就尽量不要用hash!!!
char和int转换:
cnt[(int)(cc - 'a')] += 1;
count函数:统计 26 个字母出现的次数,可以复用
class Solution {
public:
// 能用int数组就尽量不要用hash!!!!
// char和int转换:cnt[(int)(cc - 'a')] += 1;
int countCharacters(vector& words, string chars) {
vector chars_count = count(chars); // 统计字母表的字母出现次数
int res = 0;
for (string& word : words) {
vector word_count = count(word); // 统计单词的字母出现次数
if (contains(chars_count, word_count)) {
res += word.length();
}
}
return res;
}
// 检查字母表的字母出现次数是否覆盖单词的字母出现次数
bool contains(vector& chars_count, vector& word_count) {
for (int i = 0; i < 26; i++) {
if (chars_count[i] < word_count[i]) {
return false;
}
}
return true;
}
// count函数:统计 26 个字母出现的次数
vector count(string& word) {
vector counter(26, 0);
for (char c : word) {
counter[c-'a']++;
}
return counter;
}
};
// https://leetcode-cn.com/problems/find-words-that-can-be-formed-by-characters/solution/tong-ji-zi-mu-chu-xian-de-ci-shu-shu-zu-ji-qiao-cj/