LeetCode 131~135

本文深入探讨了LeetCode中的131和132题,即分割回文串问题。通过Java实现,分别展示了回溯法和动态规划两种解决方案。对于131题,采用回溯策略,递归检查子串是否为回文;132题则利用动态规划,构建最小切割次数的数组。这些算法有助于理解字符串处理和优化问题解决的方法。
摘要由CSDN通过智能技术生成

前言

本文隶属于专栏《LeetCode 刷题汇总》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!

本专栏目录结构请见LeetCode 刷题汇总

Github 配套工程

algorithm

正文

幕布

在这里插入图片描述

幕布链接

131. 分割回文串

Java: Backtracking solution.

回溯

package com.shockang.study.algorithm.java.leetcode.leetcode101_200.leetcode131.solution1;

import java.util.ArrayList;
import java.util.List;

/**
 * 回溯
 *
 * @author Shockang
 */
public class Solution {
	public List<List<String>> partition(String s) {
		List<List<String>> res = new ArrayList<>();
		List<String> list = new ArrayList<>();
		dfs(s, 0, list, res);
		return res;
	}

	public void dfs(String s, int pos, List<String> list, List<List<String>> res) {
		if (pos == s.length()) res.add(new ArrayList<>(list));
		else {
			for (int i = pos; i < s.length(); i++) {
				if (isPal(s, pos, i)) {
					list.add(s.substring(pos, i + 1));
					dfs(s, i + 1, list, res);
					list.remove(list.size() - 1);
				}
			}
		}
	}

	public boolean isPal(String s, int low, int high) {
		while (low < high) if (s.charAt(low++) != s.charAt(high--)) return false;
		return true;
	}

}

132. 分割回文串 II

Java Version, with comments and better naming. Easier to understand

动态规划

package com.shockang.study.algorithm.java.leetcode.leetcode101_200.leetcode132.solution1;

import java.util.stream.IntStream;

/**
 * @author Shockang
 */
public class Solution {
	public int minCut(String s) {
		// validate input
		if (s == null || s.length() <= 1) {
			return 0;
		}
		// dp
		int N = s.length();
		int[] dp = IntStream.range(0, N).toArray(); // initial value: dp[i] = i

		for (int mid = 1; mid < N; mid++) { // iterate through all chars as mid point of palindrome
			// CASE 1. odd len: center is at index mid, expand on both sides
			for (int start = mid, end = mid; start >= 0 && end < N && s.charAt(start) == s.charAt(end); start--, end++) {
				int newCutAtEnd = (start == 0) ? 0 : dp[start - 1] + 1;
				dp[end] = Math.min(dp[end], newCutAtEnd);
			}
			// CASE 2: even len: center is between [mid-1,mid], expand on both sides
			for (int start = mid - 1, end = mid; start >= 0 && end < N && s.charAt(start) == s.charAt(end); start--, end++) {
				int newCutAtEnd = (start == 0) ? 0 : dp[start - 1] + 1;
				dp[end] = Math.min(dp[end], newCutAtEnd);
			}
		}
		return dp[N - 1];
	}
}

133. 克隆图

官方题解

Map+DFS

package com.shockang.study.algorithm.java.leetcode.leetcode101_200.leetcode133.solution1;


import com.shockang.study.algorithm.java.leetcode.common.graph.Node;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Shockang
 */
public class Solution {
	private Map<Integer, Node> map = new HashMap<>();

	public Node cloneGraph(Node node) {
		if (node == null)
			return null;
		if (map.containsKey(node.val))
			return map.get(node.val);
		Node res = new Node(node.val);
		map.put(res.val, res);
		res.neighbors.addAll(node.neighbors.stream().map(this::cloneGraph).collect(Collectors.toList()));
		return res;
	}
}

HashMap,LinkedList,BFS

package com.shockang.study.algorithm.java.leetcode.leetcode101_200.leetcode133.solution2;

import com.shockang.study.algorithm.java.leetcode.common.graph.Node;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;

/**
 * @author Shockang
 */
public class Solution {
	public Node cloneGraph(Node node) {
		if (node == null) {
			return node;
		}
		HashMap<Node, Node> visited = new HashMap<>();
		// 将题目给定的节点添加到队列
		LinkedList<Node> queue = new LinkedList<>();
		queue.add(node);
		// 克隆第一个节点并存储到哈希表中
		visited.put(node, new Node(node.val, new ArrayList()));
		// 广度优先搜索
		while (!queue.isEmpty()) {
			// 取出队列的头节点
			Node n = queue.remove();
			// 遍历该节点的邻居
			for (Node neighbor : n.neighbors) {
				if (!visited.containsKey(neighbor)) {
					// 如果没有被访问过,就克隆并存储在哈希表中
					visited.put(neighbor, new Node(neighbor.val, new ArrayList()));
					// 将邻居节点加入队列中
					queue.add(neighbor);
				}
				// 更新当前节点的邻居列表
				visited.get(n).neighbors.add(visited.get(neighbor));
			}
		}
		return visited.get(node);
	}
}

134. 加油站

Share some of my ideas.

sumGas,sumCost,start,tank

package com.shockang.study.algorithm.java.leetcode.leetcode101_200.leetcode134.solution1;

/**
 * @author Shockang
 */
public class Solution {
	public int canCompleteCircuit(int[] gas, int[] cost) {
		int sumGas = 0;
		int sumCost = 0;
		int start = 0;
		int tank = 0;
		for (int i = 0; i < gas.length; i++) {
			sumGas += gas[i];
			sumCost += cost[i];
			tank += gas[i] - cost[i];
			if (tank < 0) {
				start = i + 1;
				tank = 0;
			}
		}
		if (sumGas < sumCost) {
			return -1;
		} else {
			return start;
		}
	}
}


135. 分发糖果

A simple solution

动态规划,初始都为 1,左一遍,右一遍

package com.shockang.study.algorithm.java.leetcode.leetcode101_200.leetcode135.solution1;

import java.util.Arrays;

/**
 * 动态规划,初始都为 1,左一遍,右一遍
 *
 * @author Shockang
 */
public class Solution {
	public int candy(int[] ratings) {
		int n = ratings.length;
		int[] candies = new int[n];
		Arrays.fill(candies, 1);
		for (int i = 1; i < n; i++) {
			if (ratings[i] > ratings[i - 1]) {
				candies[i] = candies[i - 1] + 1;
			}
		}
		int sum = candies[n - 1];
		for (int i = n - 2; i >= 0; i--) {
			if (ratings[i] > ratings[i + 1]) {
				candies[i] = Math.max(candies[i], candies[i + 1] + 1);
			}
			sum += candies[i];
		}
		return sum;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值