剑指offer【12 13 15 16 18 19】

12 矩阵中的路径

题目描述

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

class Solution {
public:
        bool hasPath(const char* matrix, int rows, int cols, const char* str)
    {
        if(matrix == nullptr || rows < 1 || cols < 1 || str == nullptr)
            return false;
        bool *visited = new bool[rows * cols];//记录是否访问
        memset(visited, 0, rows * cols);

        int pathLength = 0;
        for(int row = 0; row < rows; ++row)
        {
            for(int col = 0; col < cols; ++col)
            {
                if(hasPathCore(matrix, rows, cols, row, col, str,
                    pathLength, visited))
                {
                    return true;
                }
            }
        }

        delete[] visited;

        return false;
    }

    bool hasPathCore(const char* matrix, int rows, int cols, int row,
        int col, const char* str, int& pathLength, bool* visited)
        {
        if(str[pathLength] == '\0')//比对到结尾返回true
            return true;

        bool hasPath = false;
        if(row >= 0 && row < rows && col >= 0 && col < cols
            && matrix[row * cols + col] == str[pathLength]
            && !visited[row * cols + col])
        {
            ++pathLength;
            visited[row * cols + col] = true;

            hasPath = hasPathCore(matrix, rows, cols, row, col - 1,
                str, pathLength, visited)
                || hasPathCore(matrix, rows, cols, row - 1, col,
                    str, pathLength, visited)
                || hasPathCore(matrix, rows, cols, row, col + 1,
                    str, pathLength, visited)
                || hasPathCore(matrix, rows, cols, row + 1, col,
                    str, pathLength, visited);

            if(!hasPath)//若相邻四个格子没有匹配则返回上一个字符
            {
                --pathLength;
                visited[row * cols + col] = false;
            }
        }

        return hasPath;
    }
};

13 机器人的运动范围

题目描述

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

class Solution {
public:
	int movingCount(int threshold, int rows, int cols)
	{
		if (threshold < 0 || rows <= 0 || cols <= 0) {
			return 0;
		}
		bool *visited = new bool[rows*cols];
		for (int i = 0; i < rows*cols; ++i)
			visited[i] = false;
		int count = movingCountCore(threshold, rows, cols, 0, 0, visited);
		delete[] visited;
		return count;
	}
	int movingCountCore(int threshold, int rows, int cols, int row, int col, bool* visited) {
		int count = 0;
		//检查是否阀值,看能否进入当前格子,再判断相邻四个格子
		if (check(threshold, rows, cols, row, col, visited)) {
            visited[row*cols + col] = true;
			count = 1 + movingCountCore(threshold, rows, cols, row - 1, col, visited)
				+ movingCountCore(threshold, rows, cols, row, col - 1, visited)
				+ movingCountCore(threshold, rows, cols, row + 1, col, visited)
				+ movingCountCore(threshold, rows, cols, row, col + 1, visited);
		}
		return count;
	}
    //判断是否能进入(row,col)方格
	bool check(int threshold, int rows, int cols, int row, int col, bool*visited) {
		if (row >= 0 && row < rows&&col >= 0 && col < cols
			&&getDigitSum(row) + getDigitSum(col) <= threshold
			&& !visited[row*cols + col]) {
			return true;
		}
		return false;
	}
    //获取数位之和
	int getDigitSum(int n) {
		int sum = 0;
		while (n > 0) {
			sum += n % 10;
			n /= 10;
		}
		return sum;
	}
};

15 二进制中1的个数

题目描述

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

class Solution {
public:
     int  NumberOf1(int n) {
         int count = 0;
         unsigned int flag =1;
         while(flag){
             if(n&flag)
                 count++;
             flag=flag<<1;
         }
         return count;
         int count = 0;
         while(n)
         {
             count++;
             n=(n-1)&n;
         }
         return count;
     }
};

16 数值的整数次方

题目描述

给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方

class Solution {
public:
    bool invalidInput=false;
    double Power(double base, int e) {
        invalidInput=false;
        
        if((base==0)&&e<0){
            invalidInput=true;
            return 0.0;
        }
        unsigned int absExponent=(unsigned int)(e);
        if(e<0){
            absExponent=(unsigned int)(-e);
        }
        double result=help(base, absExponent);
        if(e<0)
            result=1.0/result;
        return result;
    }
    double help(double base, int e){
        if(e==0)
            return 1;
        if(e==1)
            return base;
        double result=help(base,e>>1);
        result*=result;
        if(e&0x1==1)
            result*=base;
        
        return result; 
    }
};

18 删除链表中的重复节点

题目描述

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。
例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* deleteDuplication(ListNode* pHead)
    {
        if(pHead == nullptr)
            return nullptr;
        
        ListNode* pPre = nullptr;
        ListNode* pNode = pHead;
        
        while(pNode != nullptr){
            ListNode* pNext = pNode->next;
            if(pNext != nullptr && pNext->val == pNode->val){
                int value = pNode->val;
                ListNode* pDel = pNode;
                //删除
                while(pDel != nullptr && pDel->val == value){
                    pNext = pDel->next;
                    delete pDel;
                    pDel = nullptr;
                    pDel = pNext;
                }
                if(pPre == nullptr)
                    pHead=pNext;
                else 
                    pPre->next=pNext;
                pNode=pNext;
            }else{
                pPre=pNode;
                pNode=pNode->next;
            }
        }
        return pHead;
    }
};

19 正则表达式匹配

题目描述

请实现一个函数用来匹配包括’.‘和’‘的正则表达式。
模式中的字符’.‘表示任意一个字符,而’
'表示它前面的字符可以出现任意次(包含0次)。
在本题中,匹配是指字符串的所有字符匹配整个模式。
例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配

class Solution {
public:
    bool match(char* str, char* pattern)
    {
        if (*str == '\0' && *pattern == '\0')
            return true;
        if (*str != '\0' && *pattern == '\0')
            return false;
        //if the next character in pattern is not '*'
        if (*(pattern+1) != '*')
        {
            if (*str == *pattern || (*str != '\0' && *pattern == '.'))
                return match(str+1, pattern+1);
            else
                return false;
        }
        //if the next character is '*'
        else
        {
            if (*str == *pattern || (*str != '\0' && *pattern == '.'))
                return match(str, pattern+2) || match(str+1, pattern);
            else
                return match(str, pattern+2);
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值