c++二维数组及例题

转自
https://leetcode-cn.com/explore/featured/card/array-and-string/199/introduction-to-2d-array/773/

定义和使用:

#include <iostream>

template <size_t n, size_t m>
void printArray(int (&a)[n][m]) {
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cout << a[i][j] << " ";
        }
        cout << endl;
    }
}

int main() {
    cout << "Example I:" << endl;
    int a[2][5];
    printArray(a);
    cout << "Example II:" << endl;
    int b[2][5] = {{1, 2, 3}};
    printArray(b);
    cout << "Example III:"<< endl;
    int c[][5] = {1, 2, 3, 4, 5, 6, 7};
    printArray(c);
    cout << "Example IV:" << endl;
    int d[][5] = {{1, 2, 3, 4}, {5, 6}, {7}};
    printArray(d);
}

在这里插入图片描述
仅有列,不含行数时,根据初始化数据确定行数。
初始化给出数目小于行数时,仅填充有有数值得几行。
行与列不平等,上述例子行和列不可替换。

在一些语言中,多维数组实际上是在内部作为一维数组实现的,而在其他一些语言中,实际上根本没有多维数组。

1. C++ 将二维数组存储为一维数组。

下图显示了大小为 M * N 的数组 A 的实际结构:

在这里插入图片描述
因此,如果我们将 A 定义为也包含 M * N 个元素的一维数组,那么实际上 A[i][j] 就等于 A[i * N + j]。

2. 在Java中,二维数组实际上是包含着 M 个元素的一维数组,每个元素都是包含有 N 个整数的数组。

下图显示了 Java 中二维数组 A 的实际结构:
在这里插入图片描述

动态二维数组

实际上是一维数组的嵌套。

指针定义法

先new一个 int* 定义行的长度;
再逐行用new初始化,定义列的长度;
删除时,逐行delete;

int** p = new int* [row];
for (int i = 0; i < row; i++)
	p[i] = new int[column];
#include <iostream>
using namespace std;

int main() {
	int row, column, k = 0;
	cin >> row >> column;

	int** p = new int* [row];
	for (int i = 0; i < row; i++)
		p[i] = new int[column];

	for (int i = 0; i < row; i++)
		for (int j = 0; j < column; j++)
			p[i][j] = ++k;

	for (int i = 0; i < row; i++) {
		for (int j = 0; j < column; j++)
			cout << p[i][j] << " ";
		cout << endl;
	}

	for (int i = 0; i < row; i++)
		delete[]p[i];
	p = NULL;
	return 0;
}

vector定义法

在vector的数据结构中,

.clear();清空数据

.size();当前vector容器内存储的元素的个数

.capacity();当前vector容器重新分配内存之前所能容纳的元素数量

.swap();函数交换

定义时,先申请行的数量,再申请列
删除时,申请一个空指针,交换值。
vector<vector>().swap§;

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

int main() {
	int row, column, k = 0;
	cin >> row >> column;

	vector<vector<int>> p;	
	p.resize(row);
	//vector<vector<int>>p(row,vector<int>());
	for(int i = 0; i < row;++i)
	   p[i].resize(column,0);

	for (int i = 0; i < row; i++) {
		for (int j = 0; j < column; j++)
			cout << p[i][j] << " ";
		cout << endl;
	}

vector<vector<int>>().swap(p); 
	return 0;
}

vector模板定义

template<typename T>
void new_array2d(std::vector<std::vector<T> > &v, int size_x, int size_y, const T& val)
{
	v.resize(size_y);
	for(int y=0; y < size_y; ++y)
		v[y].resize(size_x, val);
}

例题

对角线遍历

给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]

输出: [1,2,4,7,5,3,6,8,9]

题目分析
1、易错点:题目未说明矩形一定是正方形,矩形存在时才能取纵轴长度。
2、判断方向:X+Y 之和判断在那条对角线,偶数向上,奇数向下。
3、判断顶点:向上时顶点为上右两条边,向下时顶点为左下两条边。

在这里插入图片描述

class Solution {
public:
	vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
		vector<int> output;     
		int M = matrix.size(), N;
		if (M > 0)
		{
			N = matrix[0].size();
			int r = 0, c = 0;	
			do
			{
				output.push_back((matrix[r][c]));
			}while (nextmove(r, c, M, N));
		}
		return output;
	}

   private:
	bool nextmove(int& r, int& c, int M, int N) {
	    if (r == M - 1 && c == N - 1)
				return false;
		else if ((r + c) % 2 == 0)   //横纵坐标为偶数时向上
		{
			if (r == 0 || c==N-1 )                  //往上时,到达上右条边说明到达顶点了
			{
				if (c == N - 1)					//不能往右,只能往下
					r++;
				else
					c++;                         //否则往右
			}
			else {
				r--; c++;
				}
		}
		else if ((r + c) % 2 != 0)
		{
			if (r == M-1 ||c==0)                  //往下时,到达左下条边说明到达底部点了
			{
				if (r==M-1)					//不能往下,只能往右
					c++;
				else
					r++;                         //否则往下
			}
			else {
				r++; c--;
			}
		}
		return true;
	}
};

螺旋遍历

Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.

Example 1:

Input:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
Output: [1,2,3,6,9,8,7,4,5]
Example 2:

Input:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
Output: [1,2,3,4,8,12,11,10,9,5,6,7]

解法一:对于走过的路径新建一个map,设为-1;当连续两次转向,但是仍无路可走时候,遍历完成。

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector<int> res;
        int direction = 1;
        
        if(!matrix.empty())
        {       
                vector<vector<int>> matrix_fake(matrix.size(),vector<int>(matrix[0].size(),0));
                int r = 0, c = 0;
                res.push_back(matrix[r][c]);
                matrix_fake[r][c] = -1;
                while(nextmove(r,c,matrix_fake,direction))
                {
                    res.push_back(matrix[r][c]);
                    matrix_fake[r][c] = -1;
		        }
                
            }
            return res;
    }

    private:
        bool nextmove(int &r,int &c,vector<vector<int>> matrix,int &direction)
        {
            int r0 = r, c0 = c;
            int M = matrix.size();
            int N = matrix[0].size();
           switch (direction)
            {
            case 1:
                c0++;
                break;
            case 2:
                r0++;
                break;
            case 3:
                c0--;
                break;
            case 0:
                r0--;
                break;
                }
            if(r0<0||c0<0||r0>M-1||c0>N-1)
                {   
                    direction = (direction + 1) % 4;
                    }  
             else if (matrix[r0][c0] != 0)
             {
                    direction = (direction + 1) % 4;
             }

             switch (direction)
            {
            case 1:
                c++;
                break;
            case 2:
                r++;
                break;
            case 3:
                c--;
                break;
            case 0:
                r--;
                break;
                }

            if(r<0||c<0||r>M-1||c>N-1)
                {   
                    return false;
                    }  
             else if (matrix[r][c] != 0)
             {
                    return false;
             }
                    return true;
        }
};

解法二
更新边界值,每次遍历都转一圈,每一行或列遍历完后就更新边界值并判断是否结束。
遍历顺序:左到右,上到下,右到左,下到上。

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        if(matrix == null || matrix.length == 0) return new ArrayList<>();
        
        List<Integer> res = new ArrayList<>();
        int m = matrix.length;
        int n = matrix[0].length;
        
        int u = 0, d = m - 1, l = 0, r = n - 1;
        for(;;) {
            for(int i = l; i <= r; i ++) res.add(matrix[u][i]);
            if(++ u > d) break;
            
            for(int i = u; i <= d; i ++) res.add(matrix[i][r]);
            if(-- r < l) break;
            
            for(int i = r; i >= l; i --) res.add(matrix[d][i]);
            if(-- d < u) break;
            
            for(int i = d; i >= u; i --) res.add(matrix[i][l]);
            if(++ l > r) break;
        }
        
        return res;
    }
}

作者:一纸浮萍
来源:CSDN
原文:https://blog.csdn.net/LetJava/article/details/95523553

杨辉三角

Given a non-negative integer numRows, generate the first numRows of Pascal’s triangle.

杨辉三角

In Pascal’s triangle, each number is the sum of the two numbers directly above it.

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        vector<vector<int>> trangle;
        trangle.resize(numRows);
        for(int i=1;i<=numRows;i++)
           { 
               trangle[i-1].resize(i);
               *trangle[i-1].begin()=1;
               trangle[i-1].back()=1;
           }
        
        if(numRows>2)
           {
               for (int i = 2; i < numRows;i++)
                   for (int j = 1; j < trangle[i].size()-1;j++)
                       trangle[i][j] = trangle[i - 1][j - 1] + trangle[i - 1][j];
           }

               return trangle;
    }
};
  • 0
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值