剑指offer(1~10)题解

剑指offer(1~10)

二维数组中的查找

源代码
class Solution {
public:
    bool Find(int target, vector<vector<int> > array) {
        for(int i = 0 ; i < array.size() ; i ++){
            for( int j = array[i].size() - 1 ; j >= 0  ; j--){
                if( array[i][j] == target){
                    return true;
                } else if( target > array[i][j]) {
                    break;
                }
            }
        }
        return false;
    }
};
解析

因为数组从左到右递增,从上到下递增,于是从矩阵右上角开始找。如果比行最后一个值大,则直接到下一行找。若比一行找,这需要找的值要么再这一行要么不在矩阵中。

替换空格

源代码
class Solution {
public:
    void replaceSpace(char *str,int length) {
        int cntlength = 0;
        do{
            cntlength++;
        }while( str[cntlength] != ‘\0‘);

        for(int i = 0 ; str[i] != ‘\0‘ ;){
            if( str[i] == ‘ ‘){
                cntlength += 2;
                for(int j = cntlength + 2 ; j > i + 2 ; j--){
                    str[j] = str[j - 2];
                }
                str[i] = ‘%‘;
                str[i + 1] = ‘2‘;
                str[i + 2] = ‘0‘;
                i = i + 3;
            } else {
                i++;
            }
        }
    }
};
解析

题中给的length是字符串开辟空间的长度,不是字符串长度,需要注意一下。替换的换先计算出字符串的长度,然后找到空格后,就将相应位置的字符串后移,然后把空出来的位置替换成题目要求的字符。

从头到尾打印链表

源代码
class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        vector<int> list;
        if( head != NULL){
            while( head -> next != NULL){
            list.push_back(head -> val);
            head = head -> next;
            }
            list.push_back(head -> val);
            reverse(list.begin() , list.end());
        }
        return list;
    }
};
解析

因为返回的vector,用了vector的逆序函数完成了逆序。

重建二叉树

源代码
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        if( pre.size() == 0){
            return NULL;
        }
        TreeNode* root = new TreeNode(pre[0]);
        root -> left = NULL;
        root -> right = NULL;
        if( pre.size() == 1){
            return root;
        }
        vector<int> leftpre;
        vector<int> rightpre;
        vector<int> leftvin;
        vector<int> rightvin;
        for(int i = 0 ; i < vin.size() ; i ++){
            if( pre[0] == vin[i]){

                leftpre.assign(pre.begin() + 1, pre.begin() + i + 1);
                leftvin.assign(vin.begin(), vin.begin() + i);

                rightpre.assign(pre.begin()+ i + 1 , pre.end());
                rightvin.assign(vin.begin()+ i + 1, vin.end());

                root -> left = reConstructBinaryTree(leftpre , leftvin);
                root -> right = reConstructBinaryTree(rightpre , rightvin);
                break;
            }
        }
        return root;
    }
};
解析

中序中,在根左侧的都是左子树节点,右侧的都是右子树节点,并且可以算出左子树和右子树节点的个数,因此就可以从前序中截取左子树的前序序列和右子树的前序列。这里用了递归的方法,把左子树的前序中序,右子树的前序中序作为输入又传到函数中。完成二叉树的重建。

用两个栈实现队列

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

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

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

因为栈是先进后出,将栈中元素取出再押入新栈,新栈的出栈顺序就变成原来的逆序,即第一个栈中先进就会先出。所以将新的元素押入到栈1中,在取元素的时候,如果栈2为空,则栈1元素出栈再押入栈2中,然后再顺序将栈2元素出栈

旋转数组中的最小数字

源代码
class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if( rotateArray.size() == 0){
            return 0;
        }
        for(int i = 0 ; i < rotateArray.size() ; i ++){
            if( rotateArray[i] > rotateArray[i + 1]){
                return rotateArray[i + 1];
            }
        }
        return 0;
    }
};
解析

思路是找到的第一个元素比前面元素小的那个元素,就是要找的那个元素。不过这里的时间复杂度应该不是最小的。

斐波那契数列

源代码
class Solution {
public:
    int Fibonacci(int n) {
        if( n == 0)return 0;
        if( n == 1)return 1;
        int a1 = 1;
        int a2 = 0;
        int temp;
        for(int i = 1 ; i < n ; i ++){
            temp = a1 + a2;
            a2 = a1;
            a1 = temp;
        }
        return a1;
    }
};
解析

斐波那契数列 f(n) = f(n - 1) + f(n - 2),按此规律实现即可。

跳台阶

源代码
class Solution {
public:
    int jumpFloor(int number) {
        if(number == 0) return 0;
        if(number == 1) return 1;
        if(number == 2) return 2;
        int temp;
        int a1 = 2;
        int a2 = 1;
        for(int i = 2 ; i < number ; i ++){
            temp = a1 + a2;
            a2 = a1;
            a1 = temp;
        }
        return a1;
    }
};
解析

其实还是斐波那契数列问题。对于第n个台阶,如果第一次跳1一个,则剩下的解法是f(n-1),如果跳两个,则剩下的解法是f(n-2),即f(n) = f(n - 1) + f(n -2);

变态跳台阶

源代码
class Solution {
public:
    int jumpFloorII(int number) {
        if(number == 1)return 1;
        if(number == 2)return 2;
        if(number == 3)return 4;
        int sum = 4;
        while( number >= 4){
            sum *= 2;
            number--;
        }

        return sum;
    }
};
解析

这里类似上一题的解题思路,f(3) = f(2) + f(1) + 1;其中1为一次跳三个。而f(4) = f(3) + f(2) + f(1) + 1;而后面三项显然为f(3)所以f(4) = 2 * f(3);后面以此类推有f(n) = 2 *f(n - 1)

矩形覆盖

源代码
class Solution {
public:
    int rectCover(int number) {
        if( number == 0) return 0;
        if( number == 1) return 1;
        if( number == 2) return 2;
        int temp;
        int f1 = 2;
        int f2 = 1;
        for(int i = 2 ; i < number ; i ++){
            temp = f1 + f2;
            f2 = f1;
            f1 = temp;
        }
        return f1;
    }
};
解析

这个也是斐波那契饿数列问题

o
o
x x
o o

n为1时只有一种解法,n为2时有横竖两种解法,当n变大时,类似跳台阶问题,如果是纵向,则为f(n -1),如果为横向则为f(n - 2),有f(n) = f(n - 1) + f(n - 2)

原文地址:https://www.cnblogs.com/amoy-zhp/p/8457724.html

时间: 2024-08-23 12:21:10

剑指offer(1~10)题解的相关文章

剑指offer系列10:合并两个排序的链表

我拿到这个题的时候举的例子是链表1:1.3.5.7和链表2:2.4.6.8.我的思路是以:1为基础,将表2的每个结点插入表1.也就是说我一次性是要给新建立的链表中加入两个元素,分别是两个原始链表的头结点.这个思路我做了半天头脑一片混乱,中间指针实在不知道怎么弄了.于是我去睡了一觉,哈哈,我大概是这个世界上最会逃避的人了…… 看了答案使用了递归的方法,其实我做的时候我有想到要用递归,但是没用的原因是我一般写代码不喜欢用递归,原因有两个,一个是递归容易死循环,一个是递归的复杂度太高.但这道题真的太适

剑指offer(10)—— 斐波那契数列以及跳台阶问题

总结 2^(n-1)可以用位移操作进行: 1<< (n-1) 如果递归不好思考的话,可以找规律,代码很简单 斐波那契数列(10) 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). n<=39 public class Solution { public int Fibonacci(int n) { // 先判断n必须在范围内取值 if(n > 39 && n <= 0) return 0; // 为1直接返

剑指offer第10题

import java.util.Scanner; /* 前两种方法是看最低为是不是为1,不为1则向右移动. 第一种只能对正整数有效,对负数不行,因为负数用的是补码,最高外符号位为1,最后右移动,肯定会变成0xFFFFFFFFFF....F*/ public class FindNmuberOf1 { public static void main(String[] args) { Scanner in = new Scanner(System.in); while(in.hasNextInt(

剑指offer(10)矩形覆盖

题目描述: 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 解题方法: function rectCover(number) { // write code here if(number <= 2){ return number; } //还是斐波那契数列的一个形式转换,用n个小矩形 //第一次放了1*2的小矩形(一块就没有缺口了),剩下的和摆放n-1个小矩形放法相同 //第一次放了2*1的小矩形(放两块才没有缺口

&lt;剑指offer&gt; 第10题

题目:在O(1)时间删除链表节点 给定单向链表的一个头指针和节点指针,定义一个函数在O(1)时间删除该节点 public class Tenth { public class ListNode{ int val; ListNode next; } public static ListNode removeNode(ListNode head, ListNode toBeDeleted){ if(head == null || toBeDeleted == null){ return head;

剑指offer系列——10.矩阵覆盖

Q:我们可以用21的小矩形横着或者竖着去覆盖更大的矩形.请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? C:时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32M,其他语言64M T:@flysall 第一种情况等价于情形1中阴影部分的n-1块矩形有多少种覆盖方法,为f(n-1); 第二种情况等价于情形2中阴影部分的n-2块矩形有多少种覆盖方法,为f(n-2); 故f(n) = f(n-1) + f(n-2),还是一个斐波那契数列.... A: int r

剑指offer (10) 二进制中1的个数

题目:输入一个整数,输出该数二进制表示中1的个数. 我们可能很快写下如下代码: 1 int NumOf1InBinary(int n) 2 { 3 int count = 0; 4 while (n != 0) { 5 if (n & 1 ) { 6 ++count; 7 } 8 n >> 1; // bug!!! 9 } 10 return count; 11 } 第8行存在bug. 首先C/C++中数有无符号数和有符号数两种(我一直认为无符号数是个蛋疼的存在,滋生大量的bug) 左

《剑指offer》题解

有段时间准备找工作,囫囵吞枣地做了<剑指offer>提供的编程习题,下面是题解收集. 当初没写目录真是个坏习惯(-_-)||,自己写的东西都要到处找. 剑指Offer - 九度1524 - 复杂链表的复制 剑指Offer - 九度1509 - 树中两个结点的最低公共祖先 剑指Offer - 九度1508 - 把字符串转换成整数 剑指Offer - 九度1504 - 把数组排成最小的数 剑指Offer - 九度1503 - 二叉搜索树与双向链表 剑指Offer - 九度1390 - 矩形覆盖 剑

剑指offer编程题Java实现——面试题10二进制中1的个数

题目: 请实现一个函数,输入一个整数,输出该整数二进制表示中1的个数.例如,把9表示成二进制是1001,有2位是1,该函数输出2解法:把整数减一和原来的数做与运算,会把该整数二进制表示中的最低位的1变成0,与运算进行多少次就有多少个1. 1 package Solution; 2 /** 3 * 剑指offer面试题10:二进制中1的个数 4 * 题目:请实现一个函数,输入一个整数,输出该整数二进制表示中1的个数. 5 * 例如,把9表示成二进制是1001,有2位是1,该函数输出2 6 * 解法