leetcode刷题总结751-800

752. 打开转盘锁

  描述:

    

 

   思路:广度优先。对于求最短的,一般都是广度。

// 计算从起点 start 到终点 target 的最近距离
int BFS(Node start, Node target) {
    Queue<Node> q; // 核心数据结构
    Set<Node> visited; // 避免走回头路
    
    q.offer(start); // 将起点加入队列
    visited.add(start);
    int step = 0; // 记录扩散的步数

    while (q not empty) {
        int sz = q.size();
        /* 将当前队列中的所有节点向四周扩散 */
        for (int i = 0; i < sz; i++) {
            Node cur = q.poll();
            /* 划重点:这里判断是否到达终点 */
            if (cur is target)
                return step;
            /* 将 cur 的相邻节点加入队列 */
            for (Node x : cur.adj())
                if (x not in visited) {
                    q.offer(x);
                    visited.add(x);
                }
        }
        /* 划重点:更新步数在这里 */
        step++;
    }
}
View Code

 

754. 到达终点数字

  描述:

    

 

   思路;  从1到N一直累加, 直到SUM==TARGET, 或SUM减TARGET为正偶数. 因为在第n步往回走一次,SUM就会减少2n, 所以他们的差必须是偶数才能到.

763. 划分字母区间

  描述:

    

 

   思路:先统计每个字符的区间(遍历一遍)。然后对区间进行合并(按照第一个坐标排序,贪心)。

765. 情侣牵手

  描述:

    

 

   思路:

class Solution(object):
    def minSwapsCouples(self, row):
        """
        每两个座位成一对,假定左边的人都是合法的不变,如果TA右边的人与TA匹配则
        跳过,不匹配则找到TA的匹配对象的与TA右边的人交换。
        """
        def find_another(n):
            if n % 2 == 0:
                return n + 1
            else:
                return n - 1

        c = 0
        for i in range(0, len(row), 2):
            p1 = row[i]
            p2 = find_another(p1)
            if row[i+1] != p2:
                j = row.index(p2)
                row[i+1], row[j] = row[j], row[i+1]
                c += 1

        return c
View Code

767. 重构字符串

  描述:

    

 

   思路:将每个字符和出现的次数存入堆。每次去前两个大的元素,然后和前面一个比对,吧不同的输出,然后更新次数再次入堆。   

  一定要注意堆的性质看到题学会分析堆的可用性

768. 最多能完成排序的块 II

  描述:

    

 

   思路:

 

 769. 最多能完成排序的块

  类似于上题。

773. 滑动谜题

  描述:

    

 

   思路:广度优先;;;;A*搜索。

 

779. 第K个语法符号

  描述:

    

 

   思路:找规律。

781. 森林中的兔子

  描述:

    

 

   思路:

//要想使得兔子数量最小,那么尽量将报同样数量的视为同一颜色,但为了不矛盾,需要使用map记录对应颜色兔子最大的出现次数
报0的兔子一定是独一无二的直接++


var numRabbits = function(answers) {
    let map = new Map(), res = 0;

    for (let a of answers) {
        if (a == 0) {
            res++;
        } else if (!map.has(a)) {
            res += (1 + a);
            map.set(a, a);
        } else {
            map.set(a, map.get(a) - 1);
            if (map.get(a) == 0) {
                map.delete(a);
            }
        }
    }
    return res;
};

785. 判断二分图

  描述:

    

 

   思路:图的遍历。遇到一个节点,如果是对立色,继续便利,如果是相同,flase.如果没眼色,将其颜色改变为对立色。

787. K 站中转内最便宜的航班

  描述:

    

 

   思路:

class Solution 
{
    public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) 
    {
       int[][] g = new int[n][n];//记录的是目的地
       for(int[] f : flights)
       {
           g[f[0]][f[1]] = f[2];
       }

       PriorityQueue<int[]> heap = new PriorityQueue<>((a,b)->a[0] - b[0]);
       //集合的参数是一个comparator的lambda表达式,默认升序
       heap.offer(new int[]{0, src, K + 1});//想集合添加一个记录费用、起点和中转站+1的数组
          //K + 1是还可以走过站点的个数

       while(!heap.isEmpty())//数组为空直接返回-1
       {
           int[] cur = heap.poll();//得到集合当中添加的数组
           int price = cur[0], place = cur[1], remainStops = cur[2];

           if(place == dst)//起点等于v中点
            return price;//返回0费用0
           
           if(remainStops > 0)//中转次数》0(至少执行一次,因为remain====k+1)
           {
               for(int i = 0; i < n; i++)//小于城市数量
               {
                   if(g[place][i] > 0)//表示起点----终点的中转路线是否存在
                   {
                       heap.offer(new int[]{price + g[place][i], i, remainStops - 1});
                       //如果存在 计算路费、起点的值、中转站-1
                   }
               }
           }
       }

       return -1;
    }
}
View Code

 

 

790. 多米诺和托米诺平铺

  描述:

    

 

 

 

  思路:

    

 

 791. 自定义字符串排序

  描述:
    

 

   思路:一种巧妙的实现方法是统计 T 中每个字符出现的次数,把结果存储在数组 count 中,count[char] 表示字符 char 出现的次数。然后把在 S 中出现的字符按照在 S 中的相对顺序排列,剩余字符添加到当前字符串的后面,最终排好序的字符串顺序为 S + (未在 S 中出现的字符)。

792. 匹配子序列的单词数

  描述:

    

 

   思路:桶排序,(放弃。。。)

 

795. 区间子数组个数

  描述:
    

 

   思路: 

定义dp数组,dp[i]标识以A[i]结尾的符合条件的子数组个数,那么可以分三种情况讨论
A[i]在L和R之间,那么dp[i]的值为i-rpos,其中rpos是i之前第一个大于R的元素位置
A[i]小于L,dp[i] = dp[i-1],如果i为0则dp[i]等于0.
A[i]大于R,则dp[i] = 0.
将所有dp[i]加和就是要返回的结果.

 

797. 所有可能的路径

  描述:

      

  思路:深度优先。

799. 香槟塔

  描述;
    

 

   思路:倒满第一个层需要1背,前两层需要3杯,前3层需要6个。找到前几层是满的,然后剩余的从第i层分2i个支流流入i+1层的被子,除了边界流入一流,其余都是2流。

 

 

    

 

posted @ 2020-07-18 15:22  _Meditation  阅读(200)  评论(0编辑  收藏  举报