美文网首页
剑指 week2

剑指 week2

作者: Tsukinousag | 来源:发表于2021-03-19 10:55 被阅读0次

    1.机器人的运动范围

    是数位和,裸BFS,用pair<int,int>存下标

    class Solution {
    public:
        int book[55][55];
        
        int get_sum(pair<int,int>p)
        {
            int s=0,num1=p.first,num2=p.second;
            while(num1)
            {
                s+=(num1%10);
                num1/=10;
            }
            while(num2)
            {
                s+=(num2%10);
                num2/=10;
            }
            return s;
        }
        
        int movingCount(int threshold, int rows, int cols)
        {
            memset(book,0,sizeof book);
            queue<pair<int,int> >q;
            if(!rows||!cols)    return 0;
            
            int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
            int res=0;
            q.push({0,0});
            while(!q.empty())
            {
                auto top=q.front();
                q.pop();
                if(book[top.first][top.second]||get_sum(top)>threshold) continue;
                book[top.first][top.second]=1;
                res++;
                for(int i=0;i<4;i++)
                {
                    int newx=top.first+dx[i],newy=top.second+dy[i];
                    if(newx>=0&&newx<rows&&newy>=0&&newy<cols)
                        q.push({newx,newy});
                }
                
            }
            return res;
        }
    };
    

    2.剪绳子

    class Solution {
    public:
        int maxProductAfterCutting(int length) {
            //dp[i]表示绳子长度为i的最大乘积i~[2,n]
            //由于必须切一刀,假设切在j位置,左边长度为j,则右边长度为i-j,对于右边长度,可切可不切
            //dp[i]=max( j*(i-j) ,j*dp[i-j] )
            int dp[length+10];
            memset(dp,0,sizeof dp);
            for(int i=2;i<=length;i++)
            {
                for(int j=1;j<i;j++)
                {
                    dp[i]=max(dp[i],max(j*(i-j),j*dp[i-j]));
                }
            }
            return dp[length];
        }
    };
    

    3.二进制中1的个数

    采用unsigned int转化为无符号整数

    class Solution {
    public:
        int NumberOf1(int _n) {
            unsigned int n=_n;
            int res=0;
            while(n)
            {
                if(n&1)res++;
                n>>=1;
            }
            return res;
        }
    };
    

    4.快速幂

    注意如果指数是负数的话,需要取倒数

    class Solution {
    public:
        double Power(double x, int n) {
            typedef long long ll;
            bool is_min=n<0;
            double res=1;
            ll k=abs(ll(n));
            while(k)
            {
                if(k&1)
                    res*=x;
                x*=x;
                k>>=1;
            }
            if(is_min)  res=1/res;
            return res;
        }
    };
    

    5.在O(1)时间复杂度内删除链表结点

    由于是单链表,因此我们无法找到它的前驱节点,我们可以换一种思路,将下一个节点的值复制到当前节点,然后将下一个节点删除即可。

    时间复杂度为:O(1)

    class Solution {
    public:
        void deleteNode(ListNode* node) {
            auto p=node ->next;
            node->val=p->val;
            node->next=p->next;
            delete p;
        }
    };
    

    6.删除链表中的重复的节点

    定义一个虚拟头节点(dummy),防止头节点被删除,然后往后扫描整个链表(p),每次扫描元素相同的一段,如果这段中的元素个数多于1个,则将整段元素直接删除。

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* deleteDuplication(ListNode* head) {
            auto dummy=new ListNode(-1);
            dummy->next=head;
            
            auto p=dummy;
            while(p->next)
            {
                auto q=p->next;
                while(q&&q->val==p->next->val) q=q->next;//q存在不要忘记掉
                //间隔一个
                if(p->next->next==q)    p=p->next;
                //删掉大于等于2的间隔
                else
                    p->next=q;
            }
            return  dummy->next;
            
        }
    };
    

    7.正则表达式匹配

    对于这一类两个字符串匹配问题,可以用二维动态规划来写

    状态表示:dp[i][j]表示s[i....]和p[j.....]匹配

    状态计算:

    • 1.p[j]是正常字符,dp[i][j]=s[i]==p[j]&&dp[i+1][j+1]
    • 2.p[j]是' . ' , dp[i][j]=dp[i+1][j+1]
    • 3.p[j+1]是' * '(p[j]是b * 这样的形式)
      第一种出现0次, dp[i][j]=dp[i][j+2] ( 跳两个格子 )
      第二种出现>=1次, dp[i][j]=dp[i+1][j]

    8.调整数组顺序使奇数位于偶数前面

    类似于快排的思想,利用两个指针,其中第一个指针从前往后找,第二个指针从后往前找,第一个指针遇到的为偶数,第二个指针遇到的是奇数,且满足不相遇,就把这两个指针交换

    class Solution {
    public:
        void reOrderArray(vector<int> &array) {
            int l=0,r=array.size()-1;
            while(l<r)
            {
                while(l<r&&array[l]%2==1)l++;
                while(l<r&&array[r]%2==0)r--;
                if(l<r)
                    swap(array[l],array[r]);
            }
             
        }
    };
    

    9.链表中倒数第k个节点

    双指针

    class Solution {
    public:
        ListNode* findKthToTail(ListNode* pListHead, int k) {
            ListNode* fast=pListHead,*slow=pListHead;
            while(k--&&fast)
                fast=fast->next;
            if(k>=0) return NULL;
            else
            {
                while(fast)
                {
                    fast=fast->next;
                    slow=slow->next;
                }
            }
            return slow;
        }
    };
    

    10.链表中环的入口地址

    哈希表

    class Solution {
    public:
        unordered_map<ListNode *,int>mp;
        ListNode *entryNodeOfLoop(ListNode *head) {
            for(auto i=head;i;i=i->next)
            {
                if(mp[i]!=0)
                {
                    return i;
                }
                else
                {
                    mp[i]=1;
                }
            }
            return NULL;
        }
    };
    

    相关文章

      网友评论

          本文标题:剑指 week2

          本文链接:https://www.haomeiwen.com/subject/ojsscltx.html