Leetcode 542~553题

第五百四十二题:

#define x first
#define y second

class Solution {
public:
    vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
        if (matrix.empty() || matrix[0].empty()) return matrix;
        int n = matrix.size(), m = matrix[0].size();
        vector<vector<int>> dist(n, vector<int>(m, -1));
        typedef pair<int, int> PII;
        queue<PII> q;

        for (int i = 0; i < n; i ++ )
            for (int j = 0; j < m; j ++ )
                if (matrix[i][j] == 0) {
                    dist[i][j] = 0;
                    q.push({i, j});
                }

        int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
        while (q.size()) {
            auto t = q.front();
            q.pop();

            for (int i = 0; i < 4; i ++ ) {
                int x = t.x + dx[i], y = t.y + dy[i];
                if (x >= 0 && x < n && y >= 0 && y < m && dist[x][y] == -1) {
                    dist[x][y] = dist[t.x][t.y] + 1;
                    q.push({x, y});
                }
            }
        }

        return dist;
    }
};
class Solution {
    static int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

    public int[][] updateMatrix(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        // 初始化动态规划的数组,所有的距离值都设置为一个很大的数
        int[][] dist = new int[m][n];
        for (int i = 0; i < m; ++i) {
            Arrays.fill(dist[i], Integer.MAX_VALUE / 2);
        }
        // 如果 (i, j) 的元素为 0,那么距离为 0
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (matrix[i][j] == 0) {
                    dist[i][j] = 0;
                }
            }
        }
        // 只有 水平向左移动 和 竖直向上移动,注意动态规划的计算顺序
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (i - 1 >= 0) {
                    dist[i][j] = Math.min(dist[i][j], dist[i - 1][j] + 1);
                }
                if (j - 1 >= 0) {
                    dist[i][j] = Math.min(dist[i][j], dist[i][j - 1] + 1);
                }
            }
        }
        // 只有 水平向右移动 和 竖直向下移动,注意动态规划的计算顺序
        for (int i = m - 1; i >= 0; --i) {
            for (int j = n - 1; j >= 0; --j) {
                if (i + 1 < m) {
                    dist[i][j] = Math.min(dist[i][j], dist[i + 1][j] + 1);
                }
                if (j + 1 < n) {
                    dist[i][j] = Math.min(dist[i][j], dist[i][j + 1] + 1);
                }
            }
        }
        return dist;
    }
}
class Solution:
    def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]:
        m, n = len(matrix), len(matrix[0])
        # 初始化动态规划的数组,所有的距离值都设置为一个很大的数
        dist = [[10**9] * n for _ in range(m)]
        # 如果 (i, j) 的元素为 0,那么距离为 0
        for i in range(m):
            for j in range(n):
                if matrix[i][j] == 0:
                    dist[i][j] = 0
        # 只有 水平向左移动 和 竖直向上移动,注意动态规划的计算顺序
        for i in range(m):
            for j in range(n):
                if i - 1 >= 0:
                    dist[i][j] = min(dist[i][j], dist[i - 1][j] + 1)
                if j - 1 >= 0:
                    dist[i][j] = min(dist[i][j], dist[i][j - 1] + 1)
        # 只有 水平向右移动 和 竖直向下移动,注意动态规划的计算顺序
        for i in range(m - 1, -1, -1):
            for j in range(n - 1, -1, -1):
                if i + 1 < m:
                    dist[i][j] = min(dist[i][j], dist[i + 1][j] + 1)
                if j + 1 < n:
                    dist[i][j] = min(dist[i][j], dist[i][j + 1] + 1)
        return dist
func updateMatrix(matrix [][]int) [][]int {

    n, m := len(matrix), len(matrix[0])
    queue := make([][]int, 0)
    for i := 0; i < n; i++ {    // 把0全部存进队列,后面从队列中取出来,判断每个访问过的节点的上下左右,直到所有的节点都被访问过为止。
        for j := 0; j < m; j++ {
            if matrix[i][j] == 0 {
                point := []int{i, j}
                queue = append(queue, point)
            } else {
                matrix[i][j] = -1
            }
        }
    }
    direction := [][]int{{0, 1}, {0, -1}, {1, 0}, {-1, 0}}

    for len(queue) > 0 {  // 这里就是 BFS 模板操作了。
        point := queue[0]
        queue = queue[1:]
        for _, v := range direction {
            x := point[0] + v[0]
            y := point[1] + v[1]
            if x >= 0 && x < n && y >= 0 && y < m && matrix[x][y] == -1 {
                matrix[x][y] = matrix[point[0]][point[1]] + 1
                queue = append(queue, []int{x, y})
            }
        }
    }
    
    return matrix
}

第五百四十三题:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int ans = 0;

    int diameterOfBinaryTree(TreeNode* root) {
        dfs(root);
        return ans;
    }

    int dfs(TreeNode* root) {
        if (!root) return 0;
        int left = dfs(root->left), right = dfs(root->right);
        ans = max(ans, left + right);
        return max(left, right) + 1;
    }
};
class Solution {
    int ans;
    public int diameterOfBinaryTree(TreeNode root) {
        ans = 1;
        depth(root);
        return ans - 1;
    }
    public int depth(TreeNode node) {
        if (node == null) {
            return 0; // 访问到空节点了,返回0
        }
        int L = depth(node.left); // 左儿子为根的子树的深度
        int R = depth(node.right); // 右儿子为根的子树的深度
        ans = Math.max(ans, L+R+1); // 计算d_node即L+R+1 并更新ans
        return Math.max(L, R) + 1; // 返回该节点为根的子树的深度
    }
}
class Solution:
    def diameterOfBinaryTree(self, root: TreeNode) -> int:
        self.ans = 1
        def depth(node):
            # 访问到空节点了,返回0
            if not node:
                return 0
            # 左儿子为根的子树的深度
            L = depth(node.left)
            # 右儿子为根的子树的深度
            R = depth(node.right)
            # 计算d_node即L+R+1 并更新ans
            self.ans = max(self.ans, L + R + 1)
            # 返回该节点为根的子树的深度
            return max(L, R) + 1

        depth(root)
        return self.ans - 1
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
var max = 0
func diameterOfBinaryTree(root *TreeNode) int {
    max = 0
     if root == nil{
     	return 0
	 }

	deep(root)
  

	 return max
}

func deep(root *TreeNode)int{
	if root == nil{
		return 0
	}

	left :=deep(root.Left)
	right := deep(root.Right)
   if max < left+right {
   	max = left+right
	}
	return maxV(left,right)+1

}

func maxV(a,b int)int  {
	if a>=b{
		return a
	}else {
		return b
	}
}

第五百四十六题:

class Solution {
public:
    int removeBoxes(vector<int>& boxes) {
        int n = boxes.size(), INF = 1e8;
        vector<vector<vector<int>>> f(n, vector<vector<int>>(n, vector<int>(n + 1, -INF)));
        vector<vector<int>> g(n, vector<int>(n, -INF));

        for (int len = 1; len <= n; len ++ ) {
            for (int i = 0; i + len - 1 < n; i ++ ) {
                int j = i + len - 1;
                for (int k = 1; k <= len; k ++ ) {
                    if (len == 1) f[i][j][k] = 1;
                    else if (k == 1) f[i][j][k] = 1 + g[i + 1][j];
                    else {
                        for (int u = i + 1; u <= j - k + 2; u ++ ) {
                            if (boxes[i] != boxes[u]) continue;
                            int t = 0;
                            if (i + 1 <= u - 1) t = g[i + 1][u - 1];
                            f[i][j][k] = max(f[i][j][k], t + f[u][j][k - 1] - (k - 1) * (k - 1) + k * k);
                        }
                    }

                    g[i][j] = max(g[i][j], f[i][j][k]);
                }
            }
        }

        return g[0][n - 1];
    }
};
class Solution {
    int[][][] dp;

    public int removeBoxes(int[] boxes) {
        int length = boxes.length;
        dp = new int[length][length][length];
        return calculatePoints(boxes, 0, length - 1, 0);
    }

    public int calculatePoints(int[] boxes, int l, int r, int k) {
        if (l > r) {
            return 0;
        }
        if (dp[l][r][k] == 0) {
            int r1 = r, k1 = k;
            while (r1 > l && boxes[r1] == boxes[r1 - 1]) {
                r1--;
                k1++;
            }
            dp[l][r][k] = calculatePoints(boxes, l, r1 - 1, 0) + (k1 + 1) * (k1 + 1);
            for (int i = l; i < r1; i++) {
                if (boxes[i] == boxes[r1]) {
                    dp[l][r][k] = Math.max(dp[l][r][k], calculatePoints(boxes, l, i, k1 + 1) + calculatePoints(boxes, i + 1, r1 - 1, 0));
                }
            }
        }
        return dp[l][r][k];
    }
}
class Solution:
    def removeBoxes(self, boxes: List[int]) -> int:
        memo = {}
        # 已知boxes[l]有n个的情况下,boxes[l:r]能获得的最大积分
        def dp(l, r, n):
            nonlocal memo, boxes
            if memo.get((l, r, n)):
                return memo[(l, r, n)]
            
            # 只剩最后一个数字,直接结算
            if l == r - 1:
                return (n + 1) * (n + 1)
            
            # 发现邻居和自己相同,和他加一起结算
            if boxes[l] == boxes[l + 1]:
                return dp(l + 1, r, n + 1)
            
            # 先直接结算,之后再看有没有和自己一样的
            res = (n + 1) * (n + 1) + dp(l + 1, r, 0)

            # 已知下一个和自己不一样,从下下个开始找和自己一样的兄弟
            for l2 in range(l + 2, r):
                # 找到兄弟了
                if boxes[l2] == boxes[l]:
                    res = max(
                        res,
                        # 让自己的下一个到这个兄弟之前结算,
                        # 然后让自己和兄弟加起来结算,
                        # 然后取最大值
                        dp(l + 1, l2, 0) + dp(l2, r, n + 1)
                    )
            memo[(l, r, n)] = res
            return res
        # 初始状态为 已知boxes[0]有0个的情况下, boxes[0:]能获得的最大积分
        return dp(0, len(boxes), 0)
func removeBoxes(boxes []int) int {
    dp := [100][100][100]int{}
    var calculatePoints func(boxes []int, l, r, k int) int
    calculatePoints = func(boxes []int, l, r, k int) int {
        if l > r {
            return 0
        }
        if dp[l][r][k] == 0 {
            r1, k1 := r, k
            for r1 > l && boxes[r1] == boxes[r1 - 1] {
                r1--
                k1++
            }
            dp[l][r][k] = calculatePoints(boxes, l, r1 - 1, 0) + (k1 + 1) * (k1 + 1)
            for i := l; i < r1; i++ {
                if boxes[i] == boxes[r1] {
                    dp[l][r][k] = max(dp[l][r][k], calculatePoints(boxes, l, i, k1 + 1) + calculatePoints(boxes, i + 1, r1 - 1, 0))
                }
            }
        }
        return dp[l][r][k]
    }
    return calculatePoints(boxes, 0, len(boxes) - 1, 0)
}

func max(x, y int) int {
    if x > y {
        return x
    }
    return y
}

第五百四十七题:

class Solution {
public:
    vector<int> p;

    int find(int x) {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }

    int findCircleNum(vector<vector<int>>& M) {
        int n = M.size();
        for (int i = 0; i < n; i ++ ) p.push_back(i);

        int cnt = n;
        for (int i = 0; i < n; i ++ )
            for (int j = 0; j < n; j ++ )
                if (M[i][j] && find(i) != find(j)) {
                    p[find(i)] = find(j);
                    cnt -- ;
                }

        return cnt;
    }
};
class Solution {
    public int findCircleNum(int[][] isConnected) {
        int provinces = isConnected.length;
        int[] parent = new int[provinces];
        for (int i = 0; i < provinces; i++) {
            parent[i] = i;
        }
        for (int i = 0; i < provinces; i++) {
            for (int j = i + 1; j < provinces; j++) {
                if (isConnected[i][j] == 1) {
                    union(parent, i, j);
                }
            }
        }
        int circles = 0;
        for (int i = 0; i < provinces; i++) {
            if (parent[i] == i) {
                circles++;
            }
        }
        return circles;
    }

    public void union(int[] parent, int index1, int index2) {
        parent[find(parent, index1)] = find(parent, index2);
    }

    public int find(int[] parent, int index) {
        if (parent[index] != index) {
            parent[index] = find(parent, parent[index]);
        }
        return parent[index];
    }
}
class Solution:
    def findCircleNum(self, isConnected: List[List[int]]) -> int:
        def dfs(i: int):
            for j in range(provinces):
                if isConnected[i][j] == 1 and j not in visited:
                    visited.add(j)
                    dfs(j)
        
        provinces = len(isConnected)
        visited = set()
        circles = 0

        for i in range(provinces):
            if i not in visited:
                dfs(i)
                circles += 1
        
        return circles
func findCircleNum(isConnected [][]int) (ans int) {
    vis := make([]bool, len(isConnected))
    for i, v := range vis {
        if !v {
            ans++
            queue := []int{i}
            for len(queue) > 0 {
                from := queue[0]
                queue = queue[1:]
                vis[from] = true
                for to, conn := range isConnected[from] {
                    if conn == 1 && !vis[to] {
                        queue = append(queue, to)
                    }
                }
            }
        }
    }
    return
}

第五百五十一题:

class Solution {
public:
    bool checkRecord(string s) {
        for (int i = 0, a = 0, l = 0; i < s.size(); i ++ ) {
            if (s[i] == 'A') a ++ , l = 0;
            else if (s[i] == 'L') l ++ ;
            else l = 0;
            if (a > 1 || l > 2) return false;
        }
        return true;
    }
};
public class Solution {
    public boolean checkRecord(String s) {
        int count=0;
        for(int i=0;i<s.length() && count<2 ;i++)
            if(s.charAt(i)=='A')
                count++;
        return count<2 && s.indexOf("LLL")<0;
    }
}
class Solution:
    def checkRecord(self, s: str) -> bool:
        #判断是否存在超过两个连续的'L'
        def pending_s(s):
            count = 0
            for i in range(0, len(s)):
                if s[i] == "L":
                    count += 1
                    if count > 2:
                        return False
                else:
                    count = 0
            return True
        #不超过一个'A'(缺勤)并且不超过两个连续的'L'(迟到)
        return s.count("A") <= 1 and pending_s(s) 
func checkRecord(s string) bool {
	absentCount := 0
	lateCount := 0
	for i := 0; i < len(s); i++ {
		switch s[i] {
		case 'P':
			lateCount = 0
		case 'L':
			lateCount++
			if lateCount == 3 {
				return false
			}
		case 'A':
			lateCount = 0
			absentCount++
			if absentCount == 2 {
				return false
			}
		}
	}
	return true
}

第五百五十二题:

const int mod = 1e9 + 7, N = 100010;
int f[N][2][3];

class Solution {
public:
    int checkRecord(int n) {
        memset(f, 0, sizeof f);
        f[0][0][0] = 1;
        for (int i = 0; i < n; i ++ )
            for (int j = 0; j < 2; j ++ )
                for (int k = 0; k < 3; k ++ ) {
                    if (!j) f[i + 1][j + 1][0] = (f[i + 1][j + 1][0] + f[i][j][k]) % mod;
                    if (k + 1 <= 2) f[i + 1][j][k + 1] = (f[i + 1][j][k + 1] + f[i][j][k]) % mod;
                    f[i + 1][j][0] = (f[i + 1][j][0] + f[i][j][k]) % mod;
                }

        int res = 0;
        for (int j = 0; j < 2; j ++ )
            for (int k = 0; k < 3; k ++ )
                res = (res + f[n][j][k]) % mod;
        return res;
    }
};
public class Solution {
    long M = 1000000007;
    public int checkRecord(int n) {
        long a0l0 = 1, a0l1 = 0, a0l2 = 0, a1l0 = 0, a1l1 = 0, a1l2 = 0;
        for (int i = 0; i <= n; i++) {
            long a0l0_ = (a0l0 + a0l1 + a0l2) % M;
            a0l2 = a0l1;
            a0l1 = a0l0;
            a0l0 = a0l0_;
            long a1l0_ = (a0l0 + a1l0 + a1l1 + a1l2) % M;
            a1l2 = a1l1;
            a1l1 = a1l0;
            a1l0 = a1l0_;
        }
        return (int) a1l0;
    }
}
class Solution:
    def checkRecord(self, n: int) -> int:
        dp = [[0 for _ in range(6)] for _ in range(2)]
        dp[0][0] = 1
        for i in range(1,n+1):
            dp[i%2][0] = (dp[(i-1)%2][0] + dp[(i-1)%2][1] + dp[(i-1)%2][2])%1000000007
            dp[i%2][1] = dp[(i-1)%2][0]%1000000007
            dp[i%2][2] = dp[(i-1)%2][1]%1000000007
            dp[i%2][3] = sum(dp[(i-1)%2])%1000000007
            dp[i%2][4] = dp[(i-1)%2][3]%1000000007
            dp[i%2][5] = dp[(i-1)%2][4]%1000000007
        return sum(dp[n%2])%1000000007
class Solution:
	def checkRecord(self, n: int) -> int:
		mod=pow(10,9)+7
		# 长度、'A'出现的次数、末尾连续'L'的次数
		dp=[[[0]*3 for _ in range(2)]for _ in range(n+1)]
		# base case:长度为1,那么是'A''L''P'中的一种
		dp[1][1][0]=1 #A
		dp[1][0][1]=1 #L
		dp[1][0][0]=1 #P

		for i in range(2,n+1):
			# 若末尾是k个连续的L(即k>0for j in range(2):
				for k in range(1,3):
					dp[i][j][k]=dp[i-1][j][k-1]%mod
			# 若末尾没有L(即k=0)
			dp[i][0][0]=noA=sum(dp[i-1][0])%mod
			dp[i][1][0]=noA+sum(dp[i-1][1])%mod
		# 结果等于dp[n]的所有可能
		return sum(sum(col) for col in dp[-1])%mod

第五百五十三题:

class Solution {
public:
    string optimalDivision(vector<int>& nums) {
        int n = nums.size();
        if (n == 0) return "";
        if (n == 1) return to_string(nums[0]);
        if (n == 2) return to_string(nums[0]) + '/' + to_string(nums[1]);

        string res = to_string(nums[0]) + "/(";
        for (int i = 1; i < n - 1; i ++ )
            res += to_string(nums[i]) + '/';
        res += to_string(nums.back()) + ')';
        return res;
    }
};
public class Solution {
    public String optimalDivision(int[] nums) {
        if (nums.length == 1)
            return nums[0] + "";
        if (nums.length == 2)
            return nums[0] + "/" + nums[1];
        StringBuilder res = new StringBuilder(nums[0] + "/(" + nums[1]);
        for (int i = 2; i < nums.length; i++) {
            res.append("/" + nums[i]);
        }
        res.append(")");
        return res.toString();
    }
}
class Solution:
    def optimalDivision(self, nums: List[int]) -> str:
        return str(nums[0]) if len(nums) == 1 else str(nums[0]) + '/(' + '/'.join(list(map(str, nums[1:]))) + ')' if len(nums) > 2 else str(nums[0]) + '/' + str(nums[-1])
func optimalDivision(nums []int) string {
	var sli []string
	
	for _, n := range nums {
		sli = append(sli, strconv.Itoa(n))
	}
	
	if len(sli) < 3 {
		return strings.Join(sli, "/")
	}
	
	return sli[0] +"/(" + strings.Join(sli[1:], "/") + ")"
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不能say的秘密

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值