64滑动窗口的最大值--65矩阵中的路径--66机器人的运动范围

64滑动窗口的最大值

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

  1. 可以定义窗口的起始位置和结束位置,定义一个数组中存储最大窗口。
  2. 在滑动一次之后计算新的最大窗口push进数组中。
  3. 向后滑动过程,窗口起始位置和结束位置均向后滑动,直至结尾。
class Solution {
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        vector<int> ret;
        if(num.empty()||size<0)
            return ret;
        int start=0,end=size-1;
        while(end<num.size())
        {
            ret.push_back(MaxArray(start,end,num));
            start++,end++;
        }
        return ret;
    }
    int MaxArray(int start,int end,const vector<int>&num)
    {
        int max=num[start];
        for(int i=start+1;i<=end;i++)
        {
            if(num[i]>max)
                max=num[i];
        }
        return max;
    }
};

牛客网链接

65矩阵中的路径

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

  1. 类似这种题型都需要采用回溯法来解决,我们采用一位数组按行标记矩阵位置是否可以到达。起点位置不固定,遍历二维数组下标去试探。
  2. 回溯法通过递归实现,递归过程中,如果该位置越界、该位置不可达、该位置元素与str的字符不相等,都返回false。
  3. 当str指向/,str+1指向0时候,str走到了字符结尾位置,否则str向后移动。
  4. 该位置可达,继续向四周试探,试探之后,一定要将该位置置0,因为,不能走回头路。
class Solution{
public:
	bool hasPath(char* matrix, int rows, int cols, char* str)
	{
		int *map = new int[rows*cols];
		for (int i = 0; i < cols*rows; i++) 
			map[i] = 0;
		for (int i = 0; i < rows; i++){
			for (int j = 0; j < cols; j++){
				if (hasPathOne(matrix, i, j, rows, cols, str, map)){
					delete[] map;
					map = nullptr;
					return true;
				}
			}
		}
		return false;
	}
public:
	bool hasPathOne(char* matrix, int i, int j, int rows, int cols, char* str, int *map){
		int index = i*cols + j;
		if (i < 0 || j < 0 || i >= rows || j >= cols || map[index] == 1 || matrix[index] != *str) 
            return false;
		if (*(str+1)==0) return true;else str++;
		map[index] = 1;//该位置可达
		if (hasPathOne(matrix, i - 1, j, rows, cols, str,  map) ||
			hasPathOne(matrix, i + 1, j, rows, cols, str, map) ||
			hasPathOne(matrix, i, j - 1, rows, cols, str,  map) ||
			hasPathOne(matrix, i, j + 1, rows, cols, str,  map))
			return true;
		map[index] = 0;//不能走回头路
		return false;
	}
};

牛客网链接

66机器人的运动范围

地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?

机器人从0,0开始移动,它可以向上、下、左、右移动,我们不能确定机器人可以从哪个方向移动到某个坐标,无法使用循环遍历。正确做法是采用回溯法,使用递归函数实现,定义一个二维数组记录坐标位置机器人是否可以到达

  1. 不满足条件的坐标就返回0,对于满足条件的坐标,机器人可以走到该位置,先将map中的该位置置1,然后给结果+1,再试探该位置的四周。
  2. 对于一个位置来说,一旦我递归GetCount到该位置,说明我是可以从0,0位置走到这里的,我们只需要判断它的数位之和是否大于k,就能知道它是否可以停留到这个位置。
  3. 回溯过程一定是在rows和cols范围内,不能越界,因为递归出口位置一定在二位数组边界,也就是说,机器人可能会越界,所以二维数组行列都+1,避免机器人越界访问,造成内存泄漏。
class Solution {
public:
    int movingCount(int threshold, int rows, int cols)
    {
        vector<vector<bool>> map(rows+1);
        for(int i=0;i<rows+1;i++)
            map[i].resize(cols+1,0);
        return GetCount(threshold,0,0,rows,cols,map);
    }
    int GetCount(int key,int x,int y,int rows,int cols,vector<vector<bool>>& map)
    {
        if(x<0||x>=rows||y<0||y>=cols||AddSum(x)+AddSum(y)>key||map[x][y]==1)
            return 0;
        map[x][y]=1;
        return 1+\
            GetCount(key,x-1,y,rows,cols,map)+\
            GetCount(key,x+1,y,rows,cols,map)+\
            GetCount(key,x,y-1,rows,cols,map)+\
            GetCount(key,x,y+1,rows,cols,map);
    }
    int AddSum(int x)
    {
        int sum=0;
        while(x)
        {
            sum+=x%10;
            x=x/10;
        }
        return sum;
    }
};

牛客网链接

猜你喜欢

转载自blog.csdn.net/Vickers_xiaowei/article/details/89477790
今日推荐