剑指offer刷题笔记(2)

 
45.圆圈中最后剩下的数字  知识点:链表的遍历  注意for循环中m-1,才是找到要删除的点  创新解法还不会
class Solution {
public:
    int LastRemaining_Solution(int n, int m)
    {
        if (n <1|| m<1)
            return -1;
        list<int> numbers;
        for(int i = 0; i<n; i++)
            numbers.push_back(i);

        list<int>::iterator current;
        list<int>::iterator del;
        current = numbers.begin();
        while(numbers.size() > 1)
        {
            for(int i = 0;i<m-1;i++)
            {
                current++;
                if (current == numbers.end())
                    current = numbers.begin();   

            }

            del = current++;

            if (current  == numbers.end())
                current = numbers.begin();

            numbers.erase(del);   

        }
        return *current;
    }
};
链表中环的入口结点 
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        if (pHead->next == NULL)
            return NULL;
        ListNode* slow;
        ListNode* fast;

        slow = pHead;
        fast = pHead;
        int count = 0;
        do
        {
        slow = slow->next;
        fast = fast->next->next;
        count++;
        }while(slow != fast);

        fast = pHead;
        while(fast!=slow)
        {
            fast = fast->next;
            slow = slow->next;
        }
        return slow;
    }
};
二叉树的下一个结点  知识点;二叉树的遍历高级变种  最开始没有加father!=NULL判断,导致一直通不过,指定结点完全有可能是最后一个结点
class Solution {
public:
    TreeLinkNode* GetNext(TreeLinkNode* pNode)
    {
        if (pNode->right != NULL)
        {
            pNode = pNode->right;
            while(pNode->left!=NULL)
            {
                pNode = pNode->left;
             }
            return pNode;
        }
        else
        {
              TreeLinkNode* father = pNode->next;
              while(father->left != pNode && father != NULL)
              {
                  pNode = father ;
                  father = pNode->next;
              }


                return father;


            }
        }

};
数字在排序数组中出现的次数  知识点:二分查找      题目中说了排序数组,没有的话就用hash方法吧。
class Solution {
public:
int GetNumberOfK(vector<int> data, int k) {
    int length = data.size();
    int l = 0;
    int r = length - 1;
    int minus = -1;
    if (data[r]> data[l])
        minus = 1;

    while (l <= r)
    {
        int mid = l + (r-l)/2;
        if (data[mid] == k)
        {
            int first = mid ;
            int last = mid ;
            while (first >= 0 && data[first] == data[mid])
            {
                first--;
            }
            while (last < length &&data[last] == data[mid])
            {
                last++;
            }

            return last - first - 1;

        }
        else if (data[mid] <k)
        {
            if (minus == 1)
                l = mid + 1;
            else
                r = mid;

        }
        else
        {
            if (minus == 1)
                r = mid;
            else
                l = mid + 1;
        }
    }
    return 0;
}
};
二分查找要注意三个问题,一是数据量要大于1; 二是数据中到底有没有这个数,这关系到能不能跳出循环;有个死角是数组的最后一个数是没法判断到的。 。上面的代码就有这三个问题,下面两种方法是正确的
class Solution {
public:
int GetNumberOfK(vector<int> data, int k) {
     if (data.size()<2)
    {
        if (data.empty())
        return 0;
        if (data[0]==k)
        return 1;
        else
        return 0;
    }



    int length = data.size();
    int l = 0;
    int r = length - 1;
    int minus = -1;
    if (data[r]> data[l])
        minus = 1;


    while (l <= r)
    {
        int mid = l + (r-l)/2;
        if (data[mid] == k )
        {
            int first = mid ;
            int last = mid ;
            while (first >= 0 && data[first] == data[mid])
            {
                first--;
            }
            while (last < length &&data[last] == data[mid])
            {
                last++;
            }

            return last - first - 1;

        }

        else if (data[mid] <k)
        {
            if (minus == 1)
                l = mid + 1 ;
            else
                r = mid-1  ;

        }
        else
        {
            if (minus == 1)
                r = mid -1;
            else
                l = mid + 1;
        }
    }




    return 0;
}
};

class Solution {
public:
int GetNumberOfK(vector<int> data, int k) {
     if (data.size()<2)
    {
        if (data.empty())
        return 0;
    }



    int length = data.size();
    int l = 0;
    int r = length - 1;
    int minus = -1;
    if (data[r]> data[l])
        minus = 1;


    while (l < r)
    {
        int mid = l + (r-l)/2;
        if (data[mid] == k )
        {
            int first = mid ;
            int last = mid ;
            while (first >= 0 && data[first] == data[mid])
            {
                first--;
            }
            while (last < length &&data[last] == data[mid])
            {
                last++;
            }

            return last - first - 1;

        }

        else if (data[mid] <k)
        {
            if (minus == 1)
                l = mid + 1  ;
            else
                r = mid -1  ;  //r = mid也行

        }
        else
        {
            if (minus == 1)
                r = mid -1 ;  //r = mid 也行
            else
                l = mid + 1;
        }
    }

    if (data[l] == k)
        return 1;



    return 0;
}
};
主要是三个两个地方,一个是while要不要等于号,另一个是r = mid还是r=mid -1  如果要等于号,必须r =mid -1,否则有可能跳不出循环,r= mid -1必须数据的个数最少1个。 如果不要等于号,r = mid,r = mid -1可以只是一个数,但是会剩一个数没有判断,就是l==r的那个位置的,要拿出来单独判断。
42.左旋转字符串   找到规律了就不难了
class Solution {
public:
    string LeftRotateString(string str, int n) {
        int length = str.size();
        revise(str, 0, length-1);
        revise(str,0, length-n-1);
        revise(str, length-n, length-1);
        return str;
    }

    void revise(string&str,int begin, int  end)
        {
        int l = begin;
        int r = end;
        while(l<r)
        {
            char temp = str[r];
            str[r] = str[l];
            str[l] = temp;
            l++;
            r--;
        }


    }
};
22.栈的压入弹出队列 思路很简单,       如果stackData要不然压入一个新的数,要不然弹出一个数 
class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) {
        bool bPossible = false;
        if (pushV.empty() || popV.empty())
            return bPossible;
        std::stack<int> stackData;
         int i = 0;
        int j = 0;
        for(; i<pushV.size(), j<popV.size(); )
        {
            if (stackData.empty() ||stackData.top() != popV[j])
            {
                stackData.push(pushV[i]);
                i++;
            }

            if (stackData.top() == popV[j])
            {
                stackData.pop();
                j++;
            }
        }


    if (stackData.empty())
        bPossible = true;
    return bPossible;
    }   
}; 
和为S的连续正数序列                         知识点:尺取法
class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        int begin = 1;
        int end = 2;
        int total = begin + end;
        vector<vector<int> > result;
        while(begin<sum)
        {
            if (total == sum)
            {
                saveData(result, begin, end);
                total -=begin++;

            }

            else if (total<sum)
            {
                total += ++end;

            }

            else
            {
                total -= begin++;
            }         
        }
        return result;
    }

    void saveData(vector<vector<int> > &result, int begin, int end)
    {

        vector<int> temp;
        while(begin<=end)
        {
            temp.push_back(begin);
            begin++;
        }

        result.push_back(temp);
    }
};
二叉搜索树与双向链表        知识点:遍历     其实可以看做是求最大值的升级版visit函数修改全局变量, 因为要从小到大,所以选择中序遍历
/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
class Solution {
public:
    TreeNode* Convert(TreeNode* pRootOfTree)
    {
        if (pRootOfTree == NULL)
            return  NULL;
        TreeNode* pLastNodeInList = NULL;
        ConvertNode(pRootOfTree, &pLastNodeInList);
        TreeNode* pHeadOfList = pLastNodeInList;
        while(pHeadOfList != NULL && pHeadOfList->left!=NULL)
            pHeadOfList = pHeadOfList->left;
  //      while(  pLastNodeInList->left != NULL )
  //          pLastNodeInList = pLastNodeInList->left;
        return  pHeadOfList;
    }

    void  ConvertNode(TreeNode*pNode , TreeNode** pLastNodeInList)
    {


        if (pNode)
            {


            ConvertNode(pNode->left , pLastNodeInList);

            TreeNode* current = pNode;
            current->left = *pLastNodeInList;
            if (*pLastNodeInList != NULL)
                (*pLastNodeInList)->right = current;
            *pLastNodeInList = current;

            ConvertNode(pNode->right, pLastNodeInList);

        }
    }
};
从上往下打印二叉树  知识点;二叉树遍历, 迭代法
/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
class Solution {
public:
    vector<int> PrintFromTopToBottom(TreeNode* root) {
     vector<int> result;
        if (root==NULL)
            return result;
        std::deque<TreeNode*> dequeTreeNode;
        dequeTreeNode.push_back(root);

        while(!dequeTreeNode.empty())
        {
            TreeNode* pNode = dequeTreeNode.front();
            dequeTreeNode.pop_front();

            result.push_back(pNode->val);

            if (pNode->left != NULL)
                dequeTreeNode.push_back(pNode->left);
            if (pNode->right != NULL)
                dequeTreeNode.push_back(pNode->right);           
        }

        return result;

    }
};
数组中只出现一次的数字           知识点:是一个的升级版,三个的话那就没辙了, 三个数不相同不能保证异或结二进制中有两个1.如11,10,01;
class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
        int num = 0;
        for(int i = 0; i<data.size();i++)
            num ^= data[i];

            int onebit = num&(num -1);
            onebit = num^onebit;

            int num11 = 0;
            int num22 = 0;
            for(int i = 0; i<data.size();i++)
            {
                if (data[i]&onebit)
                    num11 ^=data[i];
                else
                    num22 ^= data[i];
            }

            *num1 = num11;
            *num2 = num22;
    }
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值