删除排序数组中的重复项

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
示例:
输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
提示:
  • 0 <= nums.length <= 3 * 104
  • -104 <= nums[i] <= 104
  • nums 已按升序排列
相关标签:数组,双指针
#pragma once
#includeclass Solution {
public:
    int removeDuplicates(std::vector& nums) {

        /*by myself
        int len = nums.size();
        int result_len = 0;
        if (len != 0) {       
            ++result_len;      //数组不为空的情况(表示第一个元素)result_len+1
        }

        for (int i = 0; i < len - 1; ++i) { if (nums[i] != nums[i + 1]) { ++result_len; //找不重复元素,result_len+1 continue; } else { for (int j = i + 1; j < len - 1; ++j) { nums[j] = nums[j + 1]; //找到重复元素,从后往前覆盖这个重复元素 } --len; //覆盖一个元素,len-1 --i; //因为找到的是重复元素,所以为了使下一次循环回退到上一个比较元素i,i-1 } } return result_len; //最终返回不重复元素的数量 */ //双指针 int len = nums.size(); if (len == 0) { return 0; //数组len为0则返回0 } int left = 0; //左右指针起始都指向第一个元素 int right = 0; for (right = 1; right < len; ++right) { //右指针向右移动遍历数组 if (nums[left] != nums[right]) nums[++left] = nums[right]; //当右指针所指元素和左指针所指元素不同时,左指针向右移动并将右指针所指元素赋值给左指针 } return left + 1; } };

买卖股票的最佳时机 II

给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 :
输入: prices = [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
注意:你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
提示:
  • 1 <= prices.length <= 3 * 104
  • 0 <= prices[i] <= 104
相关标签贪心算法 数组
#pragma once
#include#includeclass Solution {
public:
    int maxProfit(std::vector& prices) {      
        /* by myself(贪心)
        int len = prices.size();
        int gained = 0;                                //设置累计收入

        for (int i = 0; i < len-1; ++i) { if (prices[i] < prices[i + 1]) { //实现盈利的前提条件为:"前一天的股票价格低于后一天的价格" gained += (prices[i + 1] - prices[i]); } } return gained; */ //动态规划 int n = prices.size(); int(*dp)[2] = new int[n][2]; dp[0][0] = 0; //表示第一天交易后手上没有股票 dp[0][1] = -prices[0]; //表示第一天交易后手上有一支股票(第一天买了这支股票) for (int i = 1; i < n; ++i) { dp[i][0] = std::max(dp[i - 1][0], dp[i - 1][1] + prices[i]); //表示第i天交易完后手里没有股票的最大利润 //dp[i-1][0]表示前一天手上没有股票今天也不买入股票的最大利润;dp[i-1][1]+prices[i]表示前一天手上持有股票但是今天抛售这支股票后的最大利润 dp[i][1] = std::max(dp[i - 1][0] - prices[i], dp[i - 1][1]); //表示第i天交易完后手里有一支股票的最大利润 //dp[i-1][0]-prices[i]表示前一天手里没有股票但是今天买入一支股票的最大利润;dp[i-1][1]表示前一天手上持有股票且今天不抛售这支股票的最大利润 } return dp[n - 1][0]; //最后一天全部交易结束后,手上持有股票的最大利润一定低于手上没有股票的最大利润 } }; /* dp总结: 对于每天来说手上可能存在有股票和没股票俩种状态 每一天的状态只与前一天的状态有关,而与更早的状态都无关,因此我们不必存储这些无关的状态 因为每一天有两个状态(有无持股),每一天的前一天也有两个状态(有无持股),所以今天和昨天之间联系总共有四个状态: 1.今天持股,昨天持股(表示今天没卖出,没交易) 2.今天持股,昨天没股(表示今天买入) 3.今天没股,昨天持股(表示今天卖出) 4.今天没股,昨天没股(表示今天没买入,没交易) 通过不断的比较和状态转移,最终得出利润最大化 */

旋转数组

给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
进阶:
  • 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
  • 你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?
示例 :
输入: nums = [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]
提示:
  • 1 <= nums.length <= 2 * 104
  • -231 <= nums[i] <= 231 - 1
  • 0 <= k <= 105
相关标签:数组
#pragma once
#includeclass Solution {
public:
    /* by myself
    void rotate(std::vector& nums, int k) {
        int len = nums.size();
        k = k % len;

        while (k != 0) {                     //循环k%len次,同时也是移动k%len次
            int tmp = nums[len - 1];

            for (int i = len - 2; i >= 0; --i) {
                nums[i + 1] = nums[i];      //每次将第一个元素到倒数第二个元素向后移动一个位置
            }
            nums[0] = tmp;                  //且同时将数组尾部的元素移到数组头部
            --k;
        }

    }
    */

    //多次反转
    void reverse(std::vector& vec,int first,int last) {        //函数reverse用于将数组中指定范围的元素反转
        int len = vec.size();

        while (first < last) { std::swap(vec[first], vec[last]); ++first; --last; } } void rotate(std::vector& nums, int k) {
        int len = nums.size();
        k = k % len;

        reverse(nums, 0, len-1);         //将整个数组元素进行反转
        reverse(nums, 0, k - 1);         //在上面处理过后数组的基础上,将数组范围[0,k-1]的元素进行反转
        reverse(nums, k, len-1);         //最后将数组范围[k,len-1]的元素进行反转
    }

};

存在重复元素

给定一个整数数组,判断是否存在重复元素。
如果存在一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false 。
示例1:
输入: [1,2,3,4]
输出: false
示例 2:
输入: [1,1,1,3,3,4,3,2,4,2]
输出: true
相关标签:数组 哈希表
#pragma once
#include#include#includeclass Solution {
public:

    bool containsDuplicate(std::vector& nums) {

        /*排序+查找
        int len = nums.size();

        std::sort(nums.begin(), nums.end());     //排序
        for (int i = 0; i < len - 1; ++i) { if (nums[i] == nums[i + 1]) { //查找 return true; } } return false; */ //哈希表 std::unordered_sets;

        for (int x : nums) {
            if (s.find(x) != s.end()) {  //如果插入一个元素时发现该元素已经存在于哈希表中,则说明存在重复的元素
                return true;
            }
            s.insert(x);                //对于数组中每个元素,我们将它插入到哈希表中
        }

        return false;
    } 
};

/*
1、无序集是一种容器,它以不特定的顺序存储惟一的元素,并允许根据元素的值快速检索单个元素。
2、在unordered_set中,元素的值同时是唯一标识它的键。键是不可变的,只可增删,不可修改
3、在内部,unordered_set中的元素没有按照任何特定的顺序排序,而是根据它们的散列值组织成桶,从而允许通过它们的值直接快速访问单个元素(平均时间复杂度为常数)。
4、unordered_set容器比set容器更快地通过它们的键访问单个元素,尽管它们在元素子集的范围迭代中通常效率较低。
5、容器中的迭代器至少是前向迭代器。
*/

只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 :
输入: [4,1,2,1,2]
输出: 4
相关标签:位运算 哈希表
#pragma once
#include#includeclass Solution {
public:
    int singleNumber(std::vector& nums) {

        /* by myself
        std::sort(nums.begin(), nums.end());        //先排序
        int len = nums.size();

        int index = 0;
        while (index < len) { //根据题意知相同的元素只重复出现俩次,所以如果存在只出现一次的数,元素个数len为单数 if (index == len - 1) { //如果前面len-1个元素都是重复数,那么最后那个元素一定是满足条件的数 return nums[index]; } if (nums[index] != nums[index + 1]) { //如果俩俩比较过程中,出现不相等,说明这两个数中一定有要找的那个数,而且一定是前面那个(因为排序过) return nums[index]; } index += 2; //每次比较完两个元素后就跨越过这俩个元素 } return 0; */ //通过异或^ 的特点得:异或运算满***换律和结合律即a^ b^ a = b ^ a ^ a = b ^ (a ^ a) = b int result = 0; for (int x : nums) { //从头到尾将每个元素进行异或^运算,俩俩重复的元素就会被消掉(a ^ a = 0),最后得到唯一不重复的目标元素 result ^= x; } return result; } }; 

两个数组的交集 II

给定两个数组,编写一个函数来计算它们的交集。
示例 :
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]
说明:
  • 输出结果中每个元素出现的次数,应与元素在两个数组中出现次数的最小值一致。
  • 我们可以不考虑输出结果的顺序。
进阶:
  • 如果给定的数组已经排好序呢?你将如何优化你的算法?
  • 如果 nums1 的大小比 nums2 小很多,哪种方法更优?
  • 如果 nums2 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
相关标签:排序 哈希表 双指针 二分查找
#pragma once
#include#include#includeusing std::vector;

class Solution {
public:
    
    vectorintersect(vector& nums1, vector& nums2) {
        
        /*by myself(排序,双指针)
        int len1 = nums1.size();
        int len2 = nums2.size(); 
        int index_1 = 0;                      //每个数组设置一个起始指针,指向数组第一个元素
        int index_2 = 0;
        vectorvec;

        std::sort(nums1.begin(), nums1.end());     //先将俩个数组进行排序
        std::sort(nums2.begin(), nums2.end());

        while (index_1 < len1 && index_2 < len2) { //其中一个指针遍历完所在数组时,查找结束 if (nums1[index_1] == nums2[index_2]) { //向后移动俩个指针的过程中,如果所指元素相同则说明找到满足条件元素,将其加入数组vec中,同时俩个指针同时向后移动一个位置 vec.push_back(nums1[index_1]); ++index_1; ++index_2; } else if (nums1[index_1] != nums2[index_2] && nums1[index_1] > nums2[index_2]) {     //如果所指元素不相同,则将所指元素值更小的指针向后移动
                ++index_2;
                }
                else{
                    ++index_1;
                }
        }

        return vec;
        */


        //哈希表
        std::vectorvec;
        std::unordered_map<int>u_map;
        /*
        if (nums1.size() > nums2.size()) {    //优化,将数组元素较小的数组记录在哈希表中
            return intersect(nums2, nums1);
        }
        */

                                      //对于一个数字,其在交集中出现的次数等于该数字在两个数组中出现次数的最小值。
        for (int num : nums1) {       //首先遍历第一个数组,并在哈希表中记录第一个数组中每个数字以及其出现的次数
            ++u_map[num];
        }

        for (int num : nums2) {         //遍历第二个数组,查找哈希表找对应元素值,找到则说明该元素满足条件,将其加入到vec数组中,同时将对应哈希表中该元素的出现次数减1
            if (u_map.count(num)) {      //count是一个查找函数,找到返回1,没找到返回0
                vec.push_back(num);
                --u_map[num];

                if (u_map[num] == 0) {   //如果该元素在哈希表中出现次数为0,则删除该元素
                    u_map.erase(num);
                }
            }
        }

        return vec;
    }
};</int>

加一

给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 2:
输入:digits = [4,3,2,1]
输出:[4,3,2,2]
解释:输入数组表示数字 4321。
提示:
  • 1 <= digits.length <= 100
  • 0 <= digits[i] <= 9
相关标签:数组
#pragma once
#includeusing std::vector;

class Solution {
public:
    vectorplusOne(vector& digits) {
        std::vector::reverse_iterator i;            
        for (i = digits.rbegin(); i != digits.rend(); ++i) {
            (*i) = (*i + 1) % 10;           //每个元素+1后%10,如果结果是0表示进位
            if (*i != 0) {                  //上式得出结果不为0说明没有仅为,直接退出循环
                break;
            }
        }
        if (i == digits.rend()) {             //如果迭代器i为digits.rend()(即指向第一个元素之前的位置),说明直到循环结束都没有跳出循环,
            digits.insert(digits.begin(), 1); //表示一直进位,所以最终要在数组digit最前面插入元素进位1
        }

        return digits;
    }
};

移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
  • 必须在原数组上操作,不能拷贝额外的数组。
  • 尽量减少操作次数。
相关标签:数组 双指针
#pragma once
#include#includeusing std::vector;

class Solution {
public:
    void moveZeroes(vector& nums) {

        /*by myself(双指针)
     
        vector::iterator first = nums.begin();   //设置first指向第一个元素,last指向第二个元素
        vector::iterator last = nums.begin();

        while (last != nums.end()) {           //last遍历完数组结束循环
            if (*first == 0 ) {                //每次交换first和last指向的元素中 first一定指向0 
                if (*last != 0) {              //在first指向的元素为0,last指向的元素不为0的情况下交换元素,同时向后移动first和last
                    std::swap(*first, *last);
                    first++;
                    last++;
                } 
                else {           //这里表示first和last指向元素都为为0,这种情况不能移动first,
                    last++;      //而是将last向后移动寻找下个一个非0元素
                }
                
            }
            else {           //在first指向元素不是0的情况下则不满***换条件,first和last同时向后移动
                first++;     //(要使first指向元素为0,且last不能在first前面,所以first和last同时移动)
                last++;
            }
        }
       */

        //覆盖
        vector::iterator first = nums.begin();
        vector::iterator last = nums.begin();

        while (last != nums.end()) {        //last遍历完数组后结束循环 
            if (*last != 0) {               //last指向元素不为0,覆盖first指向的元素,同时first向后移动
                *first = *last;         
                first++;
            }
            last++;                         
        }
        while (first != nums.end()) {       //first指向及之后的所有元素都置0(因为上面循环过程中已经将数组中的非零元素移动到数组的前面)
            *first = 0;
            first++;
        }    
    }
};

两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 :
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
提示:
  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • 只会存在一个有效答案
进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?
相关标签:数组 哈希表
#pragma once
#include#includeusing std::vector;

class Solution {
public:
    vectortwoSum(vector& nums, int target) {

        std::unordered_map<int>hash_table;   
        int len = nums.size();

        for (int i = 0; i < len; ++i) { //遍历整个数组元素 int t = target - nums[i]; //t表示与nums[i]对应满足条件的那个值 std::unordered_map<int>::iterator itr = hash_table.find(nums[i]);    //查找在hash_table中是否存对应键t与该元素值sums[i]相同
            if (itr == hash_table.end()) {
                hash_table[t] = i;                //itr == hash_table.end()表示没找到,则将t和对应下标i插入hash_table中
            }
            else {
                return { itr->second,i };         //否则说明在hash_table中找到对应键t==sums[i],找到满足条件的两个元素(t+sums[i]=target),返回俩个元素的下标
            }
        }
       
        return {};
    }
};
</int></int>

有效的数独

请你判断一个 9x9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。
  • 数字 1-9 在每一行只能出现一次。
  • 数字 1-9 在每一列只能出现一次。
  • 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 '.' 表示。
注意:
  • 一个有效的数独(部分已被填充)不一定是可解的。
  • 只需要根据以上规则,验证已经填入的数字是否有效即可。

示例
输入:board =
{'5', '3', '.', '.', '7', '.', '.', '.', '.'}
,{'6', '.', '.', '1', '9', '5', '.', '.', '.'}
,{'.', '9', '8', '.', '.', '.', '.', '6', '.'}
,{'8', '.', '.', '.', '6', '.', '.', '.', '3'}
,{'4', '.', '.', '8', '.', '3', '.', '.', '1'}
,{'7', '.', '.', '.', '2', '.', '.', '.', '6'}
,{'.', '6', '.', '.', '.', '.', '2', '8', '.'}
,{'.', '.', '.', '4', '1', '9', '.', '.', '5'}
,{'.', '.', '.', '.', '8', '.', '.', '7', '9'}
输出:true
提示:
  • board.length == 9
  • board[i].length == 9
  • board[i][j] 是一位数字或者 '.'
相关标签:哈希表
#pragma once
#include#include#includeusing std::vector;

class Solution {
public:
    bool isValidSudoku(vector& board) {

        /*by myself(暴力解法)
        for (int i = 0; i < 9; ++i) { std::unordered_setset;              //为每一行创建一个哈希表,接下来遍历每一行
            for (int j = 0; j < 9; ++j) { if (board[i][j] == '.') { //首先跳过非数字 continue; } if (set.count(board[i][j]) == 0) { //如果该数字不在哈希表中则插入该数字,否则表示该行出现重复数字,所以返回false set.insert(board[i][j]); } else { return false; } } } for (int i = 0; i < 9; ++i) { std::unordered_setset;              //为每一列创建一个哈希表,接下来遍历每一列
            for (int j = 0; j < 9; ++j) { if (board[j][i] == '.') { //首先跳过非数字 continue; } if (set.count(board[j][i]) == 0) { //如果该数字不在哈希表中则插入该数字,否则表示该行出现重复数字,所以返回false set.insert(board[j][i]); } else { return false; } } } for (int i = 0; i < 9; i+=3) { for (int j = 0; j < 9; j+=3) { //按每三行三列为一个单元格进行遍历 std::unordered_setset;                  //为每一个单元格创建一个哈希表,接下来遍历每一个单元格
                for (int n = i; n < i + 3; ++n) { for (int m = j; m < j + 3; ++m) { if (board[n][m] == '.') { //首先跳过非数组 continue; } if (set.count(board[n][m]) == 0) { //如果该数字不在哈希表中则插入该数字,否则表示该单元格出现重复数字,所以返回false set.insert(board[n][m]); } else { return false; } } } } } return true; */ /*by myself(稍加优化,依旧暴力) for (int i = 0; i < 9; ++i) { std::unordered_setset_h;            //为每一行创建一个哈希表,接下来遍历每一行
            std::unordered_setset_l;            //为每一列创建一个哈希表,接下来遍历每一列

            for (int j = 0; j < 9; ++j) { if (board[i][j] == '.') { //首先跳过非数字 continue; } if (set_h.count(board[i][j]) == 0) { //如果该数字不在哈希表中则插入该数字,否则表示该行出现重复数字,所以返回false set_h.insert(board[i][j]); } else { return false; } } for (int j = 0; j < 9; ++j) { if (board[j][i] == '.') { //首先跳过非数字 continue; } if (set_l.count(board[j][i]) == 0) { //如果该数字不在哈希表中则插入该数字,否则表示该行出现重复数字,所以返回false set_l.insert(board[j][i]); } else { return false; } } if ((i + 3) % 3 == 0) { //三列三列的检验单元格(竖着) for (int h = 0; h < 9; h += 3) { //每三列有九行,分成三个单元格 std::unordered_setset_d;                  //为每一个单元格创建一个哈希表,接下来遍历每一个单元格

                    for (int H = h; H < h + 3; ++H) { //按每三行三列为一个单元格进行遍历 for (int L = i; L < i + 3; ++L) { if (board[H][L] == '.') { //首先跳过非数组 continue; } if (set_d.count(board[H][L]) == 0) { //如果该数字不在哈希表中则插入该数字,否则表示该单元格出现重复数字,所以返回false set_d.insert(boa `rd[H][L]); } else { return false; } } } } } } return true; */ //数组法(用数组代替哈希表建立三个查找表) int row[9][10] = { 0 }; //为9行的每一行定义一个数组,下标1-9用来标记该行的数字是否出现过(下标为0不用),数组初始化为0,每当该行数字出现时,将对应下标位置元素置1(下标值=数字值) int column[9][10] = { 0 }; //为9列的每一列定义一个数组,下标1-9用来标记该列的数字是否出现过(下标为0不用),数组初始化为0,每当该列数字出现时,将对应下标位置元素置1(下标值=数字值) int block[9][10] = { 0 }; //为9块的每一块定义一个数组,下标1-9用来标记该块的数字是否出现过(下标为0不用),数组初始化为0,每当该块数字出现时,将对应下标位置元素置1(下标值=数字值) for (int i = 0; i < 9; ++i) { for (int j = 0; j < 9; ++j) { //遍历整个board if (board[i][j] == '.') { //首先跳过非数字 continue; } int cur_number = board[i][j] - '0'; //得到该元素对应数值cur_number(从char到int),且将作为对应行列块中的下标 if (row[i][cur_number]) { //如果查找表row中的 第i行第cur_number列 对应值不为0,表示 第i行 中出现过值为cur_number的元素(所以重复出现)。则返回false return false; } if (column[j][cur_number]) { //如果查找表column中的 第j行第cur_number列 对应值不为0,表示 第j列 中出现过值为cur_number的元素。则返回false return false; } if (block[i / 3 * 3 + j / 3][cur_number]) { //如果查找表block中的 第i/3*3+j/3行 第cur_number列 对应值不为0,表示 第i/3*3+j/3块 中出现过值为cur_number的元素。则返回false return false; } row[i][cur_number] = 1; //经过上面三个条件判断可知,在对应 行列块 中之前都没有出现过,现在出现,所以将查找表中相应位置置1 column[j][cur_number] = 1; block[i / 3 * 3 + j / 3][cur_number] = 1; } } return true; } };

旋转图像

给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。
你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。

示例 :

输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]
提示:
  • matrix.length == n
  • matrix[i].length == n
  • 1 <= n <= 20
  • -1000 <= matrix[i][j] <= 1000
相关标签:数组
#pragma once
#includeusing std::vector;

class Solution {
public:

    
    void rotate(vector& matrix) {

        /*by myself(暴力解法)
        std::vectorvec;          //定义一个数组大小为n*n(n为块长度)
        for (auto i = matrix.begin(); i != matrix.end(); ++i) {   //先把块按从上到小、从左到右装入数组
            for (auto j = (*i).begin(); j != (*i).end(); ++j) {
                vec.push_back(*j);
            }
        }
        
        int n = 0;
        for (int i = matrix.size() - 1; i >= 0; --i) {      //再把数组中的元素从头到尾部,对应块按从右到左、从上到下的顺序填入
            for (int j = 0; j < matrix[i].size(); ++j) { matrix[j][i] = vec[n++]; } } */ /* 俩次折叠(分析规律法) int n = matrix.size(); for (int i = 0; i < n -1; ++i) { //先沿 右上-左下 的对角线翻转 for (int j = 0; j < n - 1 - i; ++j) { int t = matrix[i][j]; matrix[i][j] = matrix[n - 1 - j][n - 1 - i]; matrix[n - 1 - j][n - 1 - i] = t; } } for (int i = 0; i < n / 2; ++i) { //再沿 水平中线 上下翻转,最终得到顺时针90°的效果 for (int j = 0; j < n; ++j) { int t = matrix[i][j]; matrix[i][j] = matrix[n - 1 - i][j]; matrix[n - 1 - i][j] = t; } } */ //自外向内顺时针旋转 int n = matrix.size(); for (int i = 0; i < n / 2; ++i) { //设n为图像块的边长,则一共有从外向内 n/2层 需要旋转90°,i为层数起始为0,所以i<n for="">  </n>