剑指offer刷题第八天

题目描述

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007

class Solution {
public:
    int InversePairs(vector<int> data) {
        int len = data.size();
        if (len < 2) return 0;
        int result = 0;
        vector<int> copy;
        for (int i = 0; i < len; i++){
            copy.push_back(data[i]);
        }
        return InversePairsCore(data, copy, 0, len - 1) % 1000000007;
    }

    long long InversePairsCore(vector<int> &data, vector<int> &copy, int start, int end){
        long long result = 0;
        if (start == end){
            copy[start] = data[start];
            return 0;
        }
        int tempMed = start + ((end - start) >> 2);
        result += InversePairsCore(copy, data, start, tempMed);
        result += InversePairsCore(copy, data, tempMed + 1, end);
        /*
        int leftSeq = tempMed;
        int rightSeq = end;
        int tempSeq = end;
        
        while(leftSeq >= start && rightSeq > tempMed){
            if(data[leftSeq] > data[rightSeq]){
                result += rightSeq-tempMed;
                copy[tempSeq--] = data[leftSeq--];
            }else{
                copy[tempSeq--] = data[rightSeq--];
            }
        }
        while(leftSeq>=start){
            copy[tempSeq--] = data[leftSeq--];
        }
        while(rightSeq>tempMed){
            copy[tempSeq--] = data[rightSeq--];
        }*/
        int leftSeq = start;
        int rightSeq = tempMed + 1;
        int tempSeq = start;
        while (leftSeq <= tempMed && rightSeq <= end){
            if (data[leftSeq] > data[rightSeq]){
                result += (tempMed - leftSeq + 1);
                copy[tempSeq++] = data[rightSeq++];
            }
            else{
                copy[tempSeq++] = data[leftSeq++];
            }
        }
        while(leftSeq <= tempMed){
            copy[tempSeq++] = data[leftSeq++];
        }
        while(rightSeq <= end){
            copy[tempSeq++] = data[rightSeq++];
        }
        return result;
    }
};

题目描述

输入两个链表,找出它们的第一个公共结点。

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        ListNode *result = NULL;
        if(pHead1 != NULL && pHead2 != NULL){
            ListNode *tempNode1 = pHead1;
            ListNode *tempNode2 = pHead2;
            /*
            if(circle(pHead1)&& circle(pHead2) == true){
            }
            if(circle(pHead1)|| circle(pHead2) == false){
                int pLen1 = getLen(pHead1);
                int pLen2 = getLen(pHead2);
                if(pLen1 > pLen2){
                    for(int i=0;i<pLen1-pLen2;i++)
                        tempNode1 = tempNode1->next;
                    }
                }
                if(pLen1 < pLen2){
                    for(int i=0;i<pLen2-pLen1;i++)
                        tempNode2 = tempNode2->next;
                    }
                }
                while(tempNode1 != NULL && tempNode2 != NULL){
                    if(tempNode1 == tempNode2){
                        result = tempNode1;
                        break;
                    }
                    tempNode1 = tempNode1->next;
                    tempNode2 = tempNode2->next;
                }
            }*/
            int pLen1 = getLen(pHead1);
            int pLen2 = getLen(pHead2);
            if(pLen1 > pLen2){
                for(int i=0;i<pLen1-pLen2;i++){
                    tempNode1 = tempNode1->next;
                }
            }
            if(pLen1 < pLen2){
                for(int i=0;i<pLen2-pLen1;i++){
                    tempNode2 = tempNode2->next;
                }
            }
            while(tempNode1 != NULL && tempNode2 != NULL){
                if(tempNode1 == tempNode2){
                    result = tempNode1;
                    break;
                }
                tempNode1 = tempNode1->next;
                tempNode2 = tempNode2->next;
            }
        }
        return result;
    }
    int getLen(ListNode* head){
        ListNode *tempNode = head;
        int pLen = 0;
        while(tempNode != NULL){
            pLen++;
            tempNode = tempNode->next;
        }
        return pLen;
    }
};

题目描述

统计一个数字在排序数组中出现的次数。

class Solution {
public:
    int GetNumberOfK(vector<int> data, int k) {
        int kIndex = getIndex(data,0,data.size()-1,k);
        int result = 0;
        if (kIndex != -1){
            int tempIndex = kIndex;
            while (tempIndex>-1 && data[tempIndex] == k){
                result++;
                tempIndex--;
            }
            tempIndex = kIndex+1;
            while (tempIndex<data.size() && data[tempIndex] == k){
                result++;
                tempIndex++;
            }
        }
        return result;
    }
    int getIndex(vector<int> data,int start,int end, int k){
        int med = 0;
        while (start <= end){
            med = (start+end)/2;
            if(data[med]==k)return med;
            else if(data[med]<k) start=med+1;
            else end=med-1;
        }
        return -1;
    }
};

题目描述

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

/*
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)
    {
        if(pRoot == NULL){
            return 0;
        }
        int leftDepth = 1;
        int rightDepth = 1;
        if(pRoot->left != NULL){
            leftDepth += TreeDepth(pRoot->left);
        }
        if(pRoot->right != NULL){
            rightDepth += TreeDepth(pRoot->right);
        }
        return leftDepth>rightDepth?leftDepth:rightDepth;
    }
};

题目描述

输入一棵二叉树,判断该二叉树是否是平衡二叉树。

class Solution {
public:
    bool IsBalanced_Solution(TreeNode* pRoot) {
        if(pRoot==NULL)return true;
        if(pRoot->left != NULL && !IsBalanced_Solution(pRoot->left)){
            return false;
        }
        if(pRoot->right != NULL && !IsBalanced_Solution(pRoot->right)){
            return false;
        }
        int leftDepth = TreeDepth(pRoot->left);
        int rightDepth = TreeDepth(pRoot->right);
        if(abs(leftDepth-rightDepth)<2) return true;
        return false;
    }
    int TreeDepth(TreeNode* pRoot)
    {
        if(pRoot == NULL){
            return 0;
        }
        int leftDepth = 1;
        int rightDepth = 1;
        if(pRoot->left != NULL){
            leftDepth += TreeDepth(pRoot->left);
        }
        if(pRoot->right != NULL){
            rightDepth += TreeDepth(pRoot->right);
        }
        return leftDepth>rightDepth?leftDepth:rightDepth;
    }
};

题目描述

一个整型数组里除了两个数字之外,其他的数字都出现了偶数次。请写程序找出这两个只出现一次的数字。

class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int* num2) {
        int len = data.size();
        if(len == 2) return;
        int xorResult = data[0];
        for(int i = 1;i < len;i++){
            xorResult ^= data[i];
        }
        if(xorResult == 0) return;
        int indexFirst = getFirstOne(xorResult);
        for(int i = 0;i < len;i++){
            if(boolFirstIndex(data[i], indexFirst)) (* num1) ^= data[i];
            else (* num2) ^= data[i];
        }
    }
    int getFirstOne(int num){
        int indexFirst = 0;
        while(((num & 1) == 0) && (indexFirst < (8 * sizeof(int)))){
            indexFirst++;
            num = num >> 1;
        }
        return indexFirst;
    }
    bool boolFirstIndex(int num, int indexFirst){
        num = num >> indexFirst;
        return (num & 1);
    }
};

题目描述

小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!

class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        vector<vector<int>> result;
        if(sum > 1){
            int start = 1;
            int count = 0;
            for(int i = 1;i <= sum/2 + 1;i++){
                count += i;
                while(count > sum){
                    count -= start;
                    start++;
                }
                if(count == sum){
                    vector<int> oneResult;
                    for(int j = start; j <= i;j++) oneResult.push_back(j);
                    result.push_back(oneResult);
                }
            }
        }
        return result;
    }
};

题目描述

输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。

class Solution {
public:
    vector<int> FindNumbersWithSum(vector<int> array, int sum) {
        int start = 0;
        int end = array.size() - 1;
        int minValue = INT_MAX;
        vector<int> result;
        int tempSum = 0;
        while (start<end){
            tempSum = array[start] + array[end];
            if (tempSum>sum) end--;
            else{
                if (tempSum == sum){
                    tempSum = array[start] * array[end];
                    if (tempSum<minValue){
                        result.clear();
                        result.push_back(array[start]);
                        result.push_back(array[end]);
                        minValue = tempSum;
                    
                    }
                }
                start++;
            }
        }
        return result;
    }
};

题目描述

汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!

class Solution {
public:
    string LeftRotateString(string str, int n) {
        string result = "";
        int strLen = str.length();
        if (strLen != 0){
            for (int i = 0; i<strLen; i++){
                result += str[(i + n) % strLen];
            }
        }
        return result;
    }
};

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值