链表迭代翻转|二分|状态压缩bfs|数学

 

🍭lc2039.bfs+空闲时间

把网络抽象成图,用 BFS 算出 0 号节点到各节点的最短距离 d 。

结合每个节点发消息的间隔 patience[v] ,先算消息往返需要 2d 秒。

再看 2d 和 patience[v] 的关系

  • 若 2d 能被 patience[v] 整除,最后一条消息已发时长 t 就是 patience[v] ;
  • 若不能整除,t 是 2d % patience[v] 。

接着算出节点收到最后一条回复的时间是 4d - t ,下一秒 4d - t + 1 就是节点变空闲的最早时间。

所有节点里时间的最大值,就是整个网络变空闲的时间 。

 

class Solution {
public:
    int networkBecomesIdle(vector<vector<int>>& edges, vector<int>& patience)

{
        int n = patience.size();
        vector<vector<int>> g(n);


        for (auto& e : edges)

       {
            int v = e[0], w = e[1];
            g[v].push_back(w);
            g[w].push_back(v);
        }

        vector<bool> vis(n, false);
        vis[0] = true;
        queue<int> q;
        q.push(0);


        int ans = 0;
        for (int d = 0; !q.empty(); d++)

      {
            int size = q.size();
            for (int i = 0; i < size; i++)

          {
                int v = q.front();
                q.pop();
                if (v > 0)

               {
                    int p = patience[v];

//两种情况求t
                    int t = p;
                    if (2 * d % p > 0)

                   {
                        t = 2 * d % p;
                    }


                    ans = max(ans, 4 * d - t + 1);
                }


                for (int w : g[v])

                  {
                    if (!vis[w])

                    {
                        vis[w] = true;
                        q.push(w);
                    }
                }
            }
        }
        return ans;
    }
};
 

 

🍭lc847.状态压缩+多源bfs

多源bfs+位图记录每一条走过的路径,当有一条路径经过所有点时最短路径找到

 class Solution {

public:
    int shortestPathLength(vector<vector<int>>& graph) {

        const int n = graph.size();
        const int ans = (1 << n) -1;

        queue<pair<int,int>> q;

        vector<vector<int>> visit(n, vector<int>(1 << n));
        int step = 0;
        for (int i = 0; i < n; i++)

      {
            q.push({i, 1 << i});
        }

 

        while (!q.empty())

      {
            int qsz = q.size();

            for (int i = 0; i < qsz; i++)

      {
                auto p = q.front();
                q.pop();

                int node = p.first;
                int state = p.second;

                if (state == ans) return step;
                if (visit[node][state] == 1) continue;

                for (auto next : graph[node])

              {

                    q.push({next, state|(1 << next)});
                }

                visit[node][state] = 1;
            }
            step++;
        }

        return -1;


    }
};

 

 

lc459.双倍字符串

  return (s+s).find(s, 1) != s.size();

str.find(要找的子串, 开始查找的位置) ,返回的是子串第一次出现的起始索引;如果没找到,就返回一个特殊值( string::npos )

class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        return (s+s).find(s, 1) != s.size();
    }
};

 啪很快,上来就写了一个暴力...

class Solution {

public:

    bool repeatedSubstringPattern(string s) {

        int n=s.size();

        for(int i=1;i<=n/2;i++)

        {

            if(n%i==0)

            {

        string check=s.substr(0,i);

        int hand=i;

        

        while(hand<=n)

        {

            string tmp=s.substr(hand,i);

            if(tmp!=check)

                break;

            hand+=i;

        }

        if(hand>=n) return true;

            }

        }

        return false;

    }

};

 

lc367.完全平方数

闭区间二分(三步)

[0,n-1].  l<=r   .   l r mid+-1

注意long long

class Solution {
public:
    bool isPerfectSquare(int num) 
    {
        int n=num/2;
        int l=0,r=n;
        while(l<=r)
        {
            long long mid=l+(r-l)/2;
            
            if(mid*mid>num)
                r=mid-1;
            else if(mid*mid==num)
                 return true;
            else
                 l=mid+1;
        }
        return (long long)l*l==num;
    }
};

 

lc448.消失的数字 o(n)

处理到理应位置后judge

 class Solution {
public:
    vector<int> findDisappearedNumbers(vector<int>& nums) {
        vector<int> res;
        int i = 0;
        while (i < nums.size())

{
            if (nums[i] == i + 1)

            {
                i++;
                continue;
            }
            int idealIdx = nums[i] - 1;
            if (nums[i] == nums[idealIdx])

           {
                i++;
                continue;
            }

//例如 实现把数字3放到索引2的位置
            int tmp = nums[i];
            nums[i] = nums[idealIdx];
            nums[idealIdx] = tmp;
     }
        for (int i = 0; i < nums.size(); i++)

{
            if (nums[i] != i+1)

            {   //未处理
                res.push_back(i+1);
            }
  }
        return res;
    }

};

原代码 nlogn了...

class Solution {
public:
    vector<int> findDisappearedNumbers(vector<int>& nums)
    {
        vector<int> ret;
        int n=nums.size();
        sort(nums.begin(),nums.end());
       
        int k=nums.back();
        int j=1;
       
        for(int i=0;i<n;i++)
        {
            while(nums[i]>j)
            {
                ret.push_back(j);
                j++;
            }
            if(j==nums[i]) j++;
        }
       
        while(k<n)
            ret.push_back(++k);
           
        return ret;
    }
};

 

 

lc231.二的幂

二进制最高位为1,其余所有位为0

(n & (n - 1)) == 0 true

循环写法

class Solution {
public:
    bool isPowerOfTwo(int n) 
    {
        while(n)
        {
            if(n==1) return true;
            if(n&1) return false;
            n>>=1;
        }
        return false;
    }
};

计算机视角

class Solution {
public:
    bool isPowerOfTwo(int n) {
        return n > 0 && (n & (n - 1)) == 0;
    }
};
 

 

lc25

三指针,迭代翻转链表

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode* tmp = head;
        int n = 0;
        // 计算链表长度
        while (tmp) {
            n++;
            tmp = tmp->next;
        }
        if (n < k) return head;

        ListNode* newHead = nullptr;
        ListNode* cur = head;
        ListNode* prevTail = nullptr;

        // 分组处理
        while (n >= k) {
            ListNode* groupHead = cur;
            ListNode* prev = nullptr;
            ListNode* tail = cur;
            // 翻转一组 k 个节点
            for (int i = 0; i < k; i++) {
                ListNode* next = cur->next;
                cur->next = prev;
                prev = cur;
                cur = next;
            }
            if (!newHead) {
                newHead = prev;
            }
            if (prevTail) {
                prevTail->next = prev;
            }
            prevTail = tail;
            n -= k;
        }
        // 连接剩余节点
        if (cur) {
            prevTail->next = cur;
        }

        return newHead;
    }

    // 原 reverse 函数递归实现有问题,这里用迭代方式重写(也可继续用递归,不过迭代更直观)
    ListNode* reverse(ListNode* head) {
        ListNode* prev = nullptr;
        ListNode* cur = head;
        while (cur) {
            ListNode* next = cur->next;
            cur->next = prev;
            prev = cur;
            cur = next;
        }
        return prev;
    }
};
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值