LeetCode-62 划水记录 04


题目一看;
感觉可以用回溯法 就是从(0.0)开始 走到下一步 再走下一步 走到尽头了 向右边走 到尽头了回去上一个格子 再从上一个格子换一个方向 走 因为只能走2个方向 如果一个格子2个方向都走完了 就又回到上一个
通过这样的办法 可以列出所有路径 并且找到所有的路径数之和。
回溯法递归实现:
代码如下:

//递归版
void uniquePaths2(int m, int n,int H,int L,int *res)
{
    if (m == H && n == L)
    {
        (*res)++;
        return 0;
    }
    if(m<=H-1)
    uniquePaths2(m + 1, n,H,L,res);
    if(n<=L-1)
    uniquePaths2(m , n+1,H,L,res);
}
int uniquePaths(int m, int n) {

    int res = 0;
    uniquePaths2(1, 1,m,n,&res);
    return res;
}
int main()
{
    int m = 4, n = 4;
    printf("%d\n", uniquePaths(m, n));
    return 0;
}

程序跑出来没问题 用题目提供的样本数据 测试都ok

但是再大一点到 m=20 n=15的时候就超时了 随着m n的增加时间几乎也以几何级的速度增长。程序运行几秒cpu就骂人了。。。
然后我想试试迭代版的时间如何
回溯法迭代版:

//迭代版
struct Point
{
    int x, y;
};
int uniquePaths3(int m,int n)
{
    int x = 0, y = 0,lsx=0,lsy=0;
    int zt[100][100] = { 0 };
    int sum = 0;
    struct Point Yl[100][100] = { 0 };

    while (1)
    {
        if (x >= m || y >= n)//该点超出范围了 返回
        {
            lsx = Yl[x][y].x;
            lsy= Yl[x][y].y;
            x = lsx;    //返回上一点
            y = lsy;
            continue;
        }
        switch (zt[x][y])
        {
        case 0://该点未使用过 默认向下
            zt[x][y]++; //表明已经向下走了一次
            x += 1;
            Yl[x][y].x = x-1;
            Yl[x][y].y= y;
            break;
        case 1:
            zt[x][y]++; //表明已经向下走了一次
            y += 1;
            Yl[x][y].x = x ;
            Yl[x][y].y = y-1;
            break;
        case 2:         //该点下右都走完了 返回上一点
            if (x == 0 && y == 0)
            {
                return sum;
            }
            zt[x][y] = 0;
            lsx = Yl[x][y].x;
            lsy = Yl[x][y].y;
            x = lsx;    //返回上一点
            y = lsy;
            break;
        default:
            break;
        }
        if (x == m - 1 && y == n - 1 && zt[x][y] == 0)
            sum++;
    }
    return sum;
}
int main()
{
    int m = 20, n = 15;
    printf("%d\n", uniquePaths3(m, n));
    //printf("%d\n", uniquePaths(m, n));
    return 0;
}

结果效果跟递归版一样
。。。然后我就想应该是从0,0 到终点的话会出现很多重复的工作,比如m=10 n=10 从中间5,5到 9,9 点如果有N种走法 那么刚开始 0,0 开始遍历到 5,5的时候 和 1,1遍历到5,5的时候都会从5,5遍历到9,9了。这就重复工作了。可以考虑把5,5到9,9的走法记录下来,然后到5,5的时候就读取这个记录就行了。
但是不能从0,0开始
应该从9,9终点开始向左边走。
然后走到左边终点的时候
就返回到上一层的末尾
如此反复到0,0 这样的话在遍历的过程中每个点都可以获取向下和向右的走法数量 两者之和即为该点到终点的走法数;

代码如下:

#include <stdio.h>

/*
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
*/
int uniquePaths2(int m, int n,int h,int l,int **HashMap)
{
    int Sum = 0;

    if (m<0||n<0)//坐标非法
        return 0;

    if (n >= 0 && n <= l-1)//如果还不用切换到上一行
    {
        if (n >= 0 && n < l-1)//可以向右读
        {
            Sum += HashMap[m][n + 1];
        }
        if (m >= 0 && m < h-1)  //可以向下读
        {
            Sum += HashMap[m+1][n];
        }
        if (h-1 == m && l-1 == n) Sum = 1;
        HashMap[m][n] = Sum;
        //切换到上一行
        if (0 == m && n == 0)
        {

            return HashMap[0][0];
        }
        if (n == 0)
        {
            return uniquePaths2(m - 1, l-1,h,l,HashMap);//返回到上一行
        }
        else
            return uniquePaths2(m, n - 1,h,l,HashMap);

    }
    return 0;
}
int uniquePaths(int m, int n)
{
    int xhbl = 0, xhbl2 = 0;
    //int HashMap[100][100] = { 0 };//记录 leetcode中不能用全局变量 所以只能这样
    int **HashMap = malloc(sizeof(int*) * 100);
    for(xhbl=0;xhbl<100;xhbl++)
        HashMap[xhbl]=malloc(sizeof(int) * 100);
    for (xhbl = 0; xhbl < 100; xhbl++)
    {
        for (xhbl2 = 0; xhbl2 < 100; xhbl2++)
        {
            HashMap[xhbl][xhbl2] = 0;
        }
    }
    HashMap[m-1][n-1] = 1;
    return uniquePaths2(m - 1, n - 1, m, n,HashMap);
}
int main()
{

    printf("%d", uniquePaths(7, 3));
    return 0;
}

提交到leetcode:

没毛病,就是时间太慢了。。

原文地址:http://blog.51cto.com/3458905/2315491

时间: 2024-10-10 01:11:48

LeetCode-62 划水记录 04的相关文章

Leetcode 442 划水记录05

题目:**给定一个整数数组 a,其中1 ≤ a[i] ≤ n (n为数组长度), 其中有些元素出现两次而其他元素出现一次. 找到所有出现两次的元素. 你可以不用到任何额外空间并在O(n)时间复杂度内解决这个问题吗? 示例: 输入:[4,3,2,7,8,2,3,1] 输出:[2,3]** 看题目条件给的数据大小我就想用计数排序,但是怎么不申请额外空间呢?其实完全可以利用每个元素的高位数据保存信息. 但是要确定要保存的信息的范围大小比如你保存的是1-100 那你得给高8位留下来保存数据 底24位用来

LeetCode --- 62. Unique Paths

题目链接:Unique Paths A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (ma

近日LeetCode算法(记录)

近日LeetCode算法 前言:最近刷了好多leetcode算法题,大家知道,程序=数据结构+算法,由此可见,算法真的是很重要的呢.闲话少谈,切入正题,来看看小编觉得有点意思的5题算法题吧... 1. LeetCode 73:矩阵置零 难度等级:中等 题目 给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0. 示例 解题思路 这是一个二维数组,我们只需要遍历一遍这个二维数组,把元素为0的那个位置所在的行与列分别标记起来,可以放在一个HashSet中,我们都知道

Leetcode刷题记录[python]——344 Reverse String

一.前言 不是计算机专业出身,却有一颗程序猿的心. 昨日开始leetcode第一次刷题,选择了菜鸟方式,从AC率最高且难度为Easy的题开始,不管题是简单还是难,都想做个记录,既是方便以后回顾,又是以此作为一个激励,督促自己每天都能有所进步. 二.题344 Reverse String Write a function that takes a string as input and returns the string reversed. class Solution(object): def

【LeetCode在线编程记录-1】字符串按单词反转

写在前面 LeetCode(地址:https://oj.leetcode.com/)是一个在线编程网站,题目经典,测试用例完备,共计157道算法类的题目.之后我会记录我的一些练习题目,有些答案是我自己原创的(说是原创,也很可能是之前在别的地方看到的而已),有些是从讨论区看到的,我都会明确标注出处. Reverse Words in a String Given an input string, reverse the string word by word. For example, Given

LeetCode 62, 63 Unique Paths I+II

62. Unique Paths 空间可以按行优化为 O(n),也可以按列优化为O(m). class Solution { public: int uniquePaths(int m, int n) { int dp[m][n]={0}; dp[0][0]=1; for (int i=0;i<m;++i){ for (int j=0;j<n;++j){ if (i==0&&j==0) continue; dp[i][j]=0; if (j-1>=0) dp[i][j]

LeetCode 62. Unique Paths Java

题目: A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish'

Leetcode 刷题记录 &amp; VLIS学长们的战绩

November 28, 2014 Leetcode全垒打! 以此纪念.找工作的路还是很漫长.继续奋斗.有学长学姐们的督促,必须更加努力. http://mcds.cs.cmu.edu/?q=node/26 2013 Chun Chen (Twitter, San Francisco, CA) Yiwen Chen (GOOGLE, Mt. View, CA) Mengwei Ding (GOOGLE, Mt. View, CA) Ge Gao (GOOGLE, Mt. View, CA) Yu

Leetcode刷题记录[python]——349 Intersection of Two Arrays

一.前言 做了两题才慢慢摸清了leetcode的操作. 二.题349 Intersection of Two Arrays Given two arrays, write a function to compute their intersection. class Solution(object): def intersection(self, nums1, nums2): """ :type nums1: List[int] :type nums2: List[int]