剑指offer:第一个只出现一次的字符&数组中的逆序对&两个链表的第一个公共结点

34.第一个只出现一次的字符

/*
题目描述
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写)
*/
class Solution {
public:
    int FirstNotRepeatingChar(string str) {
        unordered_map<char, int> cmap;
        for(int i = 0; i < str.length(); i++)
        {
            cmap[str[i]]++;
        }
        for(int i = 0; i < str.length(); i++)
        {
            if(cmap[str[i]]==1)
                return i;
        }
        return -1;
    }
};

35.数组中的逆序对

/*
题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
*/
class Solution {
public:
    int InversePairs(vector<int> &data) {
        if (data.empty() || data.size() < 2)
            return 0;
        long long int count =  mergeSort(data, 0, data.size() - 1);
        return count%1000000007;
    }

    int mergeSort(vector<int> &data, long long left, long long right)
    {
        if (left == right)
            return 0;
        long long  mid = left + ((right - left) >> 1);
        return mergeSort(data, left, mid)%1000000007 + mergeSort(data, mid + 1, right)%1000000007 + merge(data, left, mid, right)%1000000007;
    }

    int merge(vector<int> &a, long long left, long long mid, long long right)
    {
        int *b = new int[right - left + 1];
        long long i = 0;
        long long p1 = left, p2 = mid + 1;
        long long res = 0;
        while (p1 <= mid && p2 <= right)
        {
            if (a[p1] > a[p2])
            {
                res += (right - p2 + 1);
                if(res>=1000000007)//数值过大求余
                   res%=1000000007;
                b[i] = a[p1];
                p1++;
                i++;
            }
            else
            {
                b[i++] = a[p2++];
            }
        }
        while (p1 <= mid)
            b[i++] = a[p1++];
        while (p2 <= right)
            b[i++] = a[p2++];
        for (long long i = 0; i < (right - left + 1); i++)
            a[left + i] = b[i];
        delete[] b;
        return res%1000000007;
    }
};

36.两个链表的第一个公共结点

/*
题目描述
输入两个链表,找出它们的第一个公共结点。
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        //有公共节点,公共结点后面的都相等,所以结尾相同
        if(pHead1 == NULL || pHead2 == NULL)
            return NULL;
        ListNode *p1 = pHead1, *p2 = pHead2;
        int length1 = 0, length2 = 0;
        while(p1)
        {
            length1++;
            p1 = p1->next;
        }
        while(p2)
        {
            length2++;
            p2 = p2->next;
        }
        int dif = 0;
        if(length1 > length2)
        {
            dif = length1 - length2;
            while(dif != 0)
            {
                dif--;
                pHead1 = pHead1->next;
            }
        }
        else if(length2 >= length1)
        {
            dif = length2 - length1;
            while(dif != 0)
            {
                dif--;
                pHead2 = pHead2->next;
            }
        }

        while(pHead1 != pHead2)
        {
            pHead1 = pHead1->next;
            pHead2 = pHead2->next;
        }
        return pHead1;
    }
};

猜你喜欢

转载自blog.csdn.net/foreverdongjian/article/details/82503417