剑指offer1

题目:二维数组中的查找

在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

c++:

class Solution {
public:
    bool Find(int target, vector<vector<int> > array) {
        int rowcount = array.size();//行
        int colcount = array[0].size();//列

        int i ,j;
        for( i=rowcount-1,j=0;i>=0&&j<colcount;)//注意符号,少了最后的分号
        {
            if(target==array[i][j])//等号
            return true;
            if(target>array[i][j])
            {
                j++;
                continue;//少了
            }
            if(target<array[i][j])
            {
                i--;
                continue;
            }
        }
        return false;//符号
    }
};

python:

class Solution:
    def Find(self, target,array):
        if array == []:
            return False

        rawnum = len(array)
        colnum = len(array[0])
        i = colnum - 1
        j = 0
        while i >= 0 and j < rawnum:
            if array[j][i] < target:
                j += 1
            elif array[j][i] > target:
                i -= 1
            else:
                return True
        return False

题目:替换空格

请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

c++:

class Solution {
public:
    void replaceSpace(char *str,int length) {
        if (str==NULL||length<0)
            return;
        int oldlen =0;
        int oldnum =0;
        int i = 0;
        while(str[i]!='\0')//c++中没有双引号
        {
            oldlen++;
            if (str[i]==' ')//两个等号
            {
                oldnum++;
            }
            i++;
        }
        int newlen = oldlen + oldnum*2;
        if(newlen>length)
            return;
        int poldlen = oldlen;
        int pnewlen = newlen;
        while(poldlen>=0&&pnewlen>poldlen)//>=0
        {
            if(str[poldlen]==' ')
            {
                str[pnewlen--]='0';
                str[pnewlen--]='2';
                str[pnewlen--]='%';
            }
            else
            {
                str[pnewlen--]=str[poldlen];
            }
            poldlen--;
        }
    }
};

python:

# -*- coding:utf-8 -*-
class Solution:
    # s 源字符串
    def replaceSpace(self, s):
        # write code here
        tempstr = ''
        for c in s:#看了半天没发现这里不能用括号
            if c==' ':
                tempstr = tempstr+'%20'
            else:
                tempstr = tempstr+c
        return tempstr

使用replace:

return s.replace(' ', '%20')

题目:从尾到头打印链表

c++:

class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        vector<int> value;
        if(head!=NULL)
        {
            value.insert(value.begin(),head->val);
            while(head->next!=NULL)
            {
                value.insert(value.begin(),head->next->val);
                head = head->next;
            }
        }
        return value;
    }
};

python:

class Solution:
    def printListFromTailToHead(self, listNode):
        l = []
        head = listNode
        while head:
            l.insert(0, head.val)
            head = head.next
        return l

题目:重建二叉树

c++

class Solution {

    public:

        struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in) {

            int inlen=in.size();

            if(inlen==0)

                return NULL;

            vector<int> left_pre,right_pre,left_in,right_in;

            //创建根节点,根节点肯定是前序遍历的第一个数

            TreeNode* head=new TreeNode(pre[0]);

            //找到中序遍历根节点所在位置,存放于变量gen中

            int gen=0;

            for(int i=0;i<inlen;i++)

            {

                if (in[i]==pre[0])

                {

                    gen=i;

                    break;

                }

            }

            //对于中序遍历,根节点左边的节点位于二叉树的左边,根节点右边的节点位于二叉树的右边

            //利用上述这点,对二叉树节点进行归并

            for(int i=0;i<gen;i++)

            {

                left_in.push_back(in[i]);

                left_pre.push_back(pre[i+1]);//前序第一个为根节点

            }

            for(int i=gen+1;i<inlen;i++)

            {

                right_in.push_back(in[i]);

                right_pre.push_back(pre[i]);

            }

            //和shell排序的思想类似,取出前序和中序遍历根节点左边和右边的子树

            //递归,再对其进行上述所有步骤,即再区分子树的左、右子子数,直到叶节点

           head->left=reConstructBinaryTree(left_pre,left_in);

           head->right=reConstructBinaryTree(right_pre,right_in);

           return head;

        }

    };

python:

class Solution:
    def reConstructBinaryTree(self, pre, tin):
        if not pre and not tin:
            return None
        root = TreeNode(pre[0])
        if set(pre) != set(tin):
            return None
        i = tin.index(pre[0])
        root.left = self.reConstructBinaryTree(pre[1:i+1], tin[:i])
        root.right = self.reConstructBinaryTree(pre[i+1:], tin[i+1:])
        return root

c++

class Solution
{
public:
    void push(int node) {
        stack1.push(node);
    }

    int pop() {
        int a;
        if(stack2.empty()){
            while(!stack1.empty()){
                a = stack1.top();
                stack2.push(a);
                stack1.pop();
            }
        }
        a=stack2.top();
        stack2.pop();
        return a;
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};

python

class Solution:
    def __init__(self):
        self.stack1=[]
        self.stack2=[]
    def push(self, node):
        self.stack1.append(node)
    def pop(self):
        if len(self.stack1)==0 and len(self.stack2)==0:
            return
        elif len(self.stack2)==0:
            while len(self.stack1)>0:
                self.stack2.append(self.stack1.pop())
        return self.stack2.pop()

旋转数组的最小数字

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if(rotateArray.size()==0)
            return 0;
        int left=0,right=rotateArray.size()-1,min;
        if(rotateArray[left]>=rotateArray[right])
        {
            while(left<right-1)
            {
                min=left+(right-left)/2;
                if(rotateArray[min]==rotateArray[left]&&rotateArray[right]==rotateArray[left])
                    return MinOrder(rotateArray,left,right);
                if(rotateArray[min]>=rotateArray[left])
                    left=min;
                else
                    right=min;
            }
        }
        return rotateArray[right];
    }
private:
    int MinOrder(vector<int> &num,int left,int right){
        int result = num[left];
        for(int i = left + 1;i < right;++i){
            if(num[i] < result){
                result = num[i];
            }
        }
        return result;
    }
};

斐波那契数列

class Solution {
public:
    int Fibonacci(int n) {
        int f=0,g=1;
        if(n<=0){
            return 0;
        }
        while(n--){
            g=g+f;
            f=g-f;
        }
        return f;
    }
};

跳台阶

浮点错误:您的程序运行时发生浮点错误,比如遇到了除以 0 的情况
class Solution {
public:
    int jumpFloor(int number) {

        if(number>0){
            int i=1;
            for(int j=1;j<=number/2;j++){
                i+=jiecheng(number-j)/(jiecheng(number-2*j)*jiecheng(j));
            }
            return i;
        }
        else{
            return 0;
        }
    }
    int jiecheng(int a){
        int n=1;
        for(int i=1;i<=a;i++){
            n=n*i;
        }
        return n;
    }
};
链接:https://www.nowcoder.com/questionTerminal/8c82a5b80378478f9484d87d1c5f12a4
来源:牛客网

public class Solution {
    public int JumpFloor(int target) {
        if (target <= 0) {
            return -1;
        } else if (target == 1) {
            return 1;
        } else if (target ==2) {
            return 2;
        } else {
            return  JumpFloor(target-1)+JumpFloor(target-2);
        }
    }
}

变态跳台阶

https://www.nowcoder.com/questionTerminal/22243d016f6b47f2a6928b4313c85387

矩形覆盖

class Solution {
public:
    int rectCover(int number) {
        if(number<=0){
            return 0;
        }else if(number==1){
            return 1;
        }else if(number==2){
            return 2;
        }else{
            return rectCover(number-1)+rectCover(number-2);
        }

    }
};

二进制中一的个数

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

数值的整数次方

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
第一次写的错误答案:

class Solution {
public:
    void reOrderArray(vector<int> &array) {
        int size=array.size();//读取array的方式,百度了啊。
        int i=0,j;
        while(i<size&&!tf(array[i]))
            i++;
        j=i+1;
        while(j<size){
            while(tf(array[j])){
                j++;
            }
            int tmp;
            for(int i1=j;i1>i;i1--){
                tmp=array[j];
                array[i1]=array[i1-1];
            }
            array[i]=tmp;
            i++;
        }
    }
    bool tf(int n){
        if(n%2==0)
            return true;
        return false;
    }
};

调整数组顺序使奇数位于偶数前面

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

class Solution {
public:
    void reOrderArray(vector<int> &array) {
        int size=array.size();
        int i=0,j;
        while(i<size&&!tf(array[i]))
            i++;
        j=i+1;
        while(j<size){
            while(j<=size&&tf(array[j])){
                j++;
            }
            if(j==size)
                continue;
            int tmp;
            for(int i1=j;i1>i;i1--){
                tmp=array[j];
                array[i1]=array[i1-1];
            }
            array[i]=tmp;
            i++;
        }
    }
    bool tf(int n){
        if(n%2==0)
            return true;
        return false;
    }
};
class Solution {
public:
    void reOrderArray(vector<int> &array) {
        int size=array.size();
        int i=0,j;
        while(i<size&&!tf(array[i]))
            i++;
        j=i+1;
        while(j<size){
            while(j<size&&tf(array[j])){
                j++;
            }
            if(j<size){
                int tmp=array[j];
                for(int i1=j;i1>i;i1--){
                    array[i1]=array[i1-1];
                }
                array[i]=tmp;
            }else
                break;
            i++;
        }
    }
    bool tf(int n){
        if(n%2==0)
            return true;
        return false;
    }
};
class Solution {
public:
    void reOrderArray(vector<int> &array) {
        int len=array.size();
        if(len==0||len==1)
            return;
        vector<int> res;
        for(int i=0;i<len;i++)
        {
            if((array[i]&0x1)== 1)//注意此处判断奇偶性的方法,用&2的方法问什么就出错呢
                res.push_back(array[i]);
        }
        for(int i=0;i<len;i++)
        {
            if((array[i]&0x1)==0)//注意此处判断奇偶性的方法
                res.push_back(array[i]);
        }
        array = res;
    }
};

链表中倒数第k个节点

输入一个链表,输出该链表中倒数第k个结点。

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        //定义快慢指针,快的先走k步,然后两个一起向后移动;
        if(pListHead==nullptr||k==0)
            return nullptr;
        ListNode *pAhead=pListHead;
        ListNode *pAfter=pListHead;
        for(int i=0;i<k-1;i++){
            if(pAhead->next!=nullptr)
                pAhead=pAhead->next;
            else
                return nullptr;
        }
        while(pAhead->next!=nullptr){
            pAhead=pAhead->next;
            pAfter=pAfter->next;
        }
        return pAfter;
    }
};

反转链表

输入一个链表,反转链表后,输出链表的所有元素。

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        ListNode* p;
        ListNode* p1;
        ListNode* p2;

        p1=nullptr;
        p2=pHead;
        while(p2!=nullptr){
            p=p2->next;
            p2->next=p1;
            p1=p2;
            p2=p;
        }
        return p1;
    }
};

合并两个排序的链表

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        ListNode *p;
        if(pHead1==nullptr){
            return pHead2;
        }else if(pHead2==nullptr){
            return pHead1;
        }
        if(pHead1->val<=pHead2->val){
            p=pHead1;
            pHead1->next = Merge(pHead1->next, pHead2);
        }else{
            p=pHead2;
            pHead2->next = Merge(pHead1, pHead2->next);
        }
        return p;
    }
};

使用递归方法的关键两步:为什么要是pHead1->next =后面的递归呢?。
pHead1->next = Merge(pHead1->next, pHead2);
pHead2->next = Merge(pHead1, pHead2->next);

二叉搜索树的后序遍历

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

二叉搜索树的定义详情见每日或百度。
利用迭代的方法,首先从头提取出小于最后一个数的数组,再提取大于最后一个数的数组,若刚好把所有的数提取完,则满足二叉搜索树的条件,然后再分别判断左右子树是不是同样满足条件。

二叉树中和为某一值

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
class Solution {
    vector<vector<int>> result;
    vector<int> row;
    public:
    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
        row.push_back(root->val);
        expectNumber=expectNumber-root->val;
        if(expectNumber==0&&root->left==nullptr&&root->right==nullptr){
            result.push_back(row);
        }else{
            if(root->left)FindPath(root->left,expectNumber);
            if(root->right)FindPath(root->right,expectNumber);
        }
        row.pop_back();
        return result;
    }
};

上面是一个发生错误的代码:
段错误:您的程序发生段错误,可能是数组越界,堆栈溢出(比如,递归,调用层数太多)等情况引起。

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
class Solution {
    vector<vector<int>> result;
    vector<int> row;
    public:
    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
        if(root)isresult(root,expectNumber);
        return result;
    }
    void isresult(TreeNode* root,int expectNumber){
        row.push_back(root->val);
        if(expectNumber-root->val==0&&root->left==nullptr&&root->right==nullptr){
            result.push_back(row);
        }else{
            if(root->left)isresult(root->left,expectNumber-root->val);
            if(root->right)isresult(root->right,expectNumber-root->val);
        }
        row.pop_back();
    }
};

估计上一个错误代码错误出现在不应该直接在原函数上直接递归,直接递归的话return result就会输出很多次,输出混乱。
下面代码是在函数外定义变量,这样可以原函数和递归函数都可以对其进行处理,递归函数用于处理变量,原函数用于返回值。

复杂链表的复制

/*
struct RandomListNode {
    int label;
    struct RandomListNode *next, *random;
    RandomListNode(int x) :
            label(x), next(NULL), random(NULL) {
    }
};
*/
class Solution {
public:
    //复制原始链表的任意一个节点N并创建新节点N’,再把N'连接到N的后面
    void CloneNodes(RandomListNode* pHead){
        RandomListNode* pNode=pHead;
        while(pNode!=nullptr){
            RandomListNode* pCloned=new RandomListNode(0);
            pCloned->label=pNode->label;
            pCloned->next=pNode->next;
            pCloned->random=nullptr;

            pNode->next=pCloned;

            pNode=pCloned->next;
        }
    }
    //如果原始链表上的节点N的random指向s,则对应的赋值
    //节点N’的random执行指向s的下一个节点s‘
    void ConnectRandomNodes(RandomListNode* pHead){
        RandomListNode* pNode=pHead;
        while(pNode!=nullptr){
            RandomListNode* pCloned=pNode->next;
            if(pNode->random!=nullptr){//这里如果没有if会报错:段错误:您的程序发生段错误,可能是数组越界,堆栈溢出(比如,递归,调用层数太多)等情况引起。
                pCloned->random=pNode->random->next;
            }
            pNode=pCloned->next;
        }
    }
    //把得到的链表拆成两个链表,奇数位置上的节点组成原始链表,偶数
    //位置上的节点组成复制链表。
    RandomListNode* ReconnectNodes(RandomListNode* pHead){
        RandomListNode* pNode=pHead;
        RandomListNode* pClonedHead=nullptr;
        RandomListNode* pClonedNode=nullptr;

        //初始化
        if(pNode!=nullptr){
            pClonedHead=pClonedNode=pNode->next;
            pNode->next=pClonedNode->next;
            pNode=pNode->next;
        }
        //循环
        while(pNode!=nullptr){
            pClonedNode->next=pNode->next;
            pClonedNode=pClonedNode->next;
            pNode->next=pClonedNode->next;
            pNode=pNode->next;
        }
        return pClonedHead;
    }
    //三步合为一步
    RandomListNode* Clone(RandomListNode* pHead)
    {
        CloneNodes(pHead);
        ConnectRandomNodes(pHead);
        return ReconnectNodes(pHead);
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值