剑指offer编程题目汇总(更新中。。)

本文提供了一系列经典的编程题目解答,包括二叉树深度计算、跳台阶问题、斐波那契数列、二进制中1的个数等。采用C/C++语言实现,涉及递归、循环及数据结构的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在牛客网上练题的题解,传送门:http://www.nowcoder.com/ta/coding-interviews?page=1

二叉树的深度

输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

C/C++

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
class Solution {
public:
    int TreeDepth(TreeNode* pRoot)
    {
        int right, left;
        int maxdepth;

        if(pRoot == NULL)
            return 0;

        right = TreeDepth(pRoot->right);
        left = TreeDepth(pRoot->left);

        maxdepth = right>left?right:left;

        return maxdepth+1;
    }
};


变态跳台阶

一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

因为n级台阶,第一步有n种跳法:跳1级、跳2级、到跳n级
跳1级,剩下n-1级,则剩下跳法是f(n-1)
跳2级,剩下n-2级,则剩下跳法是f(n-2)
所以f(n)=f(n-1)+f(n-2)+…+f(1)
因为f(n-1)=f(n-2)+f(n-3)+…+f(1)
所以f(n)=2*f(n-1)

C/C++

class Solution {
public:
    int jumpFloorII(int number) {
        if(number==0)
            return 1;
        if(number==1)
            return 1;
        return 2*jumpFloorII(number-1);
    }
};


斐波那契数列

大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项

递归会溢出,还是默默的循环吧。

C/C++

class Solution {
public:
    int Fibonacci(int n) {
        int a, b, c;
        a = b = 1;
        if(n==0)
            return 0;
        if(n<=2 && n>0)
            return 1;
        for(int i = 3; i <= n; i++){
            c = a+b;
            a = b;
            b = c;
        }
        return c;
    }
};


二进制中1的个数

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

C/C++

class Solution {
public:
     int  NumberOf1(int n) {
         int cnt = 0;
         while(n){
             n = n&(n-1);
             cnt++;
         }
         return cnt;
     }
};


替换空格

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

C/C++

class Solution {
public:
    void replaceSpace(char *str,int length) {
        int i, j, k;
        for(i = 0; i < length; i++){
            if(str[i]==' '){
                for(k = 0, j = length-1; j-i >= 2; j--, k++){
                    str[length-k+1] = str[j];
                }
                str[length-k+1] = str[j];
                str[j+1] = '0';
                str[j] = '2';
                str[j-1] = '%';
                length+=2;
            }
        }
    }
};


跳台阶

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

对于本题,前提只有一次跳1阶或者2阶的跳法。
1. 如果两种跳法,1阶或者2阶,那么假定第一次跳的是一阶,那么剩下的是n-1个台阶,跳法是f(n-1);
2. 假定第一次跳的是2阶,那么剩下的是n-2个台阶,跳法是f(n-2)
3. 由a、b假设可以得出总跳法为: f(n) = f(n-1) + f(n-2)
4. 然后通过实际的情况可以得出:只有一阶的时候 f(1) = 1 ,只有两阶的时候可以有 f(2) = 2
5. 可以发现最终得出的是一个斐波那契数列

C/C++

class Solution {
public:
    int jumpFloor(int number) {
        if(number == 1)
            return 1;
        if(number == 2)
            return 2;
        return jumpFloor(number-1)+jumpFloor(number-2);
    }
};


二维数组中的查找

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

输入描述:

array: 待查找的二维数组
target:查找的数字

输出描述:

查找到返回true,查找不到返回false

C/C++

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

        int x, y;
        x = n-1;   //行
        y = 0;     //列
        while(x>=0 && y<m){
            if(target > array[x][y])
                y++;
            else if(target < array[x][y])
                x--;
            else
                return true;
        }
        return false;
    }
};


用两个栈实现队列

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

C/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;
};


矩形覆盖

我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

其实一个一个枚举一下,发现是个斐波那契数列

C/C++

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


从尾到头打印链表

输入一个链表,从尾到头打印链表每个节点的值。

输入描述:

输入为链表的表头

输出描述:

输出为需要打印的“新链表”的表头

C/C++代码,要求返回vector

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


链表中倒数第k个结点

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

C/C++

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        if (pListHead == NULL || k < 0){
            return NULL;
        }

        ListNode* pre = pListHead;
        ListNode* res = pListHead;

        int cnt = 0;

        while(pre != NULL){
            if(cnt == k-1){
               while(pre->next != NULL){
                    pre = pre->next;
                    res = res->next;
               }
               return res;
            }
            pre = pre->next;
            cnt++;
        }

        return NULL;
    }
};


反转链表

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

C/C++

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if(pHead == NULL){
            return NULL;
        }

        ListNode *pre, *cur, *nex;
        pre = NULL;
        cur = nex = pHead;
        while( nex!=NULL )
        {
            nex = nex->next;
            cur->next = pre;
            pre = cur;
            cur = nex;
        }
        return pre;

    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值