Leecode初级学习数据结构篇——数组与字符串(一)

一、数组与字符串

1、寻找数组的中心索引


请计算数组的 中心下标 

数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。

如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。

如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。


完整代码如下:(前缀和等于后缀和)

​
#include<iostream>
#include<vector>
#include<numeric>
using namespace std;

class Solution {
public:
    int pivotindex(vector <int>& nums) {
        if (nums.empty())
        {
            return -1;
        }
        int left_sum = 0, right_sum = accumulate(nums.begin(), nums.end(), 0); //累加求和
        for (int i = 0; i < nums.size(); i++)
        {
            left_sum += nums[i];
            if (i > 0)
            {
              right_sum -= nums[i-1];
            } 
            if (left_sum == right_sum)
            {
                cout << i << endl;
                return i;
            }
        }
        return -1;
        
    }

    void define(vector <int> &b, vector <int>::iterator& Iter1)
    {
        int d;
        cout << "请输入输入数字的个数:" << endl;
        scanf_s("%d", &d);
        cout << "请输入数字:" << endl;
        for (int i = 0; i < d; i++)   //容器的初始化
        {
            int a;
            scanf_s("%d",&a);
            b.push_back(a);
        }
        cout << "容器中的数字是:(";     //容器中数字的遍历
        for (Iter1 = b.begin(); Iter1 != b.end(); Iter1++)
        {
            cout << *Iter1 << " ";
        }
        cout << ")." << endl;
    }
};

int main()
{
    Solution a;
    vector <int> c;
    vector <int>::iterator it;
    a.define(c,it);
    cout << a.pivotindex(c) << endl;;
    return 0;
}

​

运行结果如下:

2、搜索插入位置


给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。


代码如下:(遍历,二分法)

​
​
​
//遍历

class Solution
{
public:
    int searchInsert(vector<int>& a, int target)
    {
        for (int i = 0; i < a.size(); i++)
        {
           if(target<=a[i])
           {
              return i;
           }
        }
        return a.size();
    }
};


​//二分法

class Solution
{
public:
    int searchInsert(vector<int>& a, int target)
    {
        int left = 0, right = (a.size() - 1);
        while (left < right)
        {
            int mid = left + (right - left) / 2;
            if (a[mid]==target)
            {
                return mid;
            }
            else if (a[mid]>target)
            {
                right = mid - 1;

            }
            else if (a[mid] <target)
            {
                left = mid + 1;;

            }
        }            //搜索完后,left=right=mid
        return a[left] < target ? left + 1 : left;
    }
}

​

​

运行结果:

3、合并区间


以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。


完整代码如下:

#include<iostream>
#include<vector>
#include<algorithm>  //sort函数头文件
using namespace std;

class Solution
{
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) //返回值是二维数组类型
    {
        int n = intervals.size();
        if (n == 1)
            return intervals;
        sort(intervals.begin(), intervals.end());   //先变成有序数组
        vector<vector<int>> vec;
        vec.push_back(intervals[0]);
        int j = 0;
        for (int i = j + 1; i < n; i++) {//如果前一个数组的最后一个数大于后面数组的第一个数,即有交集
            if (intervals[i][0] <= vec[j][1])
                vec[j][1] = max(vec[j][1], intervals[i][1]);//前一个数组的最后一个数赋值为数组的最大值
            else {
                vec.push_back(intervals[i]);  //正常赋值
                j++;
            }
        }
        return vec;
    }
    void print(vector<vector<int>>& cd)    //下标法打印二维数组
    {

        for (int i = 0; i < cd.size(); i++)  //容器的个数
        {
            for (int j = 0; j < cd[i].size(); j++)  //每个容器中的值
            {
                cout << cd[i][j] <<" ";
            }
            cout << endl;
        }
    }
};

int main()
{
    Solution ab;
    vector<vector<int>> c = {         //直接赋值
        {1,3},{2,6},{8,10},{15,18}
    };
    vector<vector<int> > d;
    d = ab.merge(c);
    ab.print(d);
    return 0;
}

运行结果:

4、旋转矩阵


给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。不占用额外内存空间能否做到?


题目分析:

   对角旋转:(蓝色表示步骤)

小小漫

 代码如下:

​
class Solution
{
public:
    vector<vector<int>> rorate(vector<vector<int>>& a)
    {
        int n;
        n = a.size();
       //对角旋转
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < i; j++)   //具体看下图
            {
                swap(a[i][j], a[j][i]);
            }
        }
       //镜面旋转
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n/2; j++)
            {
                swap(a[i][j], a[i][n - j - 1]);
            }
        }
        /*for (int i = 0; i < n; i++)        //reverse函数会将(begin,end)区间内的函数全部逆序
        {
              reverse(a[i].begin(), a[i].end());   //函数在<algorithm>头文件下
        }*/     
        return a;
    }
}

​

运行结果:

 五、零矩阵


编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。


 代码如下:

六、对角线遍历


给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素。


分析:

   由于每条对角线的x+y(num)值相等

   规律为:若num为偶数时,x=num;  若num为奇数时,y=num

   当x值或y值越界时,让x=行数减一 ,y=列数减一

代码如下:

class Solution {
public:
   
    vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
        vector<int> ans;
        if(matrix.empty())
            return ans;
        int row = matrix.size(), col = matrix[0].size(), c = 0, r = 0;
        for(int i=0;i < row+col-1;i++)   //对角线x+y值一定相同
        {
            if(i % 2)  //对角线值为奇数时
            {
                c = (i<col) ? i : col-1;  //和小于行数时(左上三角矩阵),i=col  否则i=col-1(不能超过边界)
                r = i - c;
                while(c >= 0 && r < row)
                    ans.push_back(matrix[r++][c--]);
            }
            else     //对角线值为奇数时
            {
                r = (i<row) ? i : row-1;
                c = i - r;
                while(c < col && r >= 0)
                    ans.push_back(matrix[r--][c++]);
            }
        }
        return ans;
        
    }
};

运行结果:

class Solution {
public:
    vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
        vector<int> ans;
        if(matrix.empty())
            return ans;
        int row = matrix.size(), col = matrix[0].size(), c = 0, r = 0;
        for(int i=0;i < row+col-1;i++)
        {
            if(i % 2)
            {
                c = (i<col) ? i : col-1;
                r = i - c;
                while(c >= 0 && r < row)
                    ans.push_back(matrix[r++][c--]);
            }
            else
            {
                r = (i<row) ? i : row-1;
                c = i - r;
                while(c < col && r >= 0)
                    ans.push_back(matrix[r--][c++]);
            }
        }
        return ans;
        
    }
};


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值