1103. 分糖果 II
//暴力
class Solution {
public int[] distributeCandies(int candies, int num_people) {
int[] ans = new int[num_people];
int i = 0;
while (candies != 0) {
ans[i % num_people] += Math.min(candies, i + 1);
candies -= Math.min(candies, i + 1);
i += 1;
}
return ans;
}
}
class Solution {
public int[] distributeCandies(int candies, int num_people) {
int[] nums = new int[num_people];
int j=1;
while (candies>0) {
for (int i = 0; i < nums.length&&candies>0; i++) {
if (candies>j) {
nums[i]+=j;
}else {
nums[i]+=candies;
}
candies = candies-j;
j++;
}
}
return nums;
}
}
46. 全排列
//回溯法
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> output = new LinkedList();
ArrayList<Integer> nums_lst = new ArrayList<Integer>();
for (int num : nums)
nums_lst.add(num);
int n = nums.length;
backtrack(n, nums_lst, output, 0);
return output;
}
public void backtrack(int n,
ArrayList<Integer> nums,
List<List<Integer>> output,
int first) {
if (first == n)
output.add(new ArrayList<Integer>(nums));
for (int i = first; i < n; i++) {
Collections.swap(nums, first, i);
backtrack(n, nums, output, first + 1);
Collections.swap(nums, first, i);
}
}
}
//重点看看!!!
/*
backtrack的公式:
result = []
def backtrack(路径, 选择列表):
if 满足结束条件:
result.add(路径)
return
for 选择 in 选择列表:
做选择
backtrack(路径, 选择列表)
撤销选择
*/
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
List<Integer> list = new ArrayList<>();
backtrack(res, list, nums);
return res;
}
public void backtrack(List<List<Integer>> res, List<Integer> list, int[] nums) {
if(list.size() == nums.length) {
res.add(new ArrayList<Integer>(list));
return;
}
for(int num : nums) {
//List.contains() 方法用于判断列表中是否包含指定元素。如果列表中包含指定元素,则返回 true,否则返回 false。
if(!list.contains(num)) {
list.add(num);
backtrack(res, list, nums);
list.remove(list.size() - 1);
}
}
}
}
647. 回文子串
//动态规划
class Solution {
public int countSubstrings(String s) {
int res = 0;
int n = s.length();
// dp[i][j] 表示[i,j]的字符是否为回文子串
boolean[][] dp = new boolean[n][n];
// 注意,外层循环要倒着写,内层循环要正着写
// 因为要求dp[i][j] 需要知道dp[i+1][j-1]
for(int i=n-1; i>=0; i--){
for(int j=i; j<n; j++){
// (s.charAt(i)==s.charAt(j) 时,当元素个数为1,2,3个时,一定为回文子串
if(s.charAt(i)==s.charAt(j) && (j-i<=2 || dp[i+1][j-1])){
dp[i][j] = true;
res++;
}
}
}
return res;
}
}
class Solution {
public int countSubstrings(String S) {
int N = S.length(), ans = 0;
for (int center = 0; center <= 2*N-1; ++center) {
int left = center / 2;
int right = left + center % 2;
while (left >= 0 && right < N && S.charAt(left) == S.charAt(right)) {
ans++;
left--;
right++;
}
}
return ans;
}
}
//马拉车算法
class Solution {
public int countSubstrings(String S) {
char[] A = new char[2 * S.length() + 3];
A[0] = '@';
A[1] = '#';
A[A.length - 1] = '$';
int t = 2;
for (char c: S.toCharArray()) {
A[t++] = c;
A[t++] = '#';
}
int[] Z = new int[A.length];
int center = 0, right = 0;
for (int i = 1; i < Z.length - 1; ++i) {
if (i < right)
Z[i] = Math.min(right - i, Z[2 * center - i]);
while (A[i + Z[i] + 1] == A[i - Z[i] - 1])
Z[i]++;
if (i + Z[i] > right) {
center = i;
right = i + Z[i];
}
}
int ans = 0;
for (int v: Z) ans += (v + 1) / 2;
return ans;
}
}
你知道的越多,你不知道的越多。
有道无术,术尚可求,有术无道,止于术。
如有其它问题,欢迎大家留言,我们一起讨论,一起学习,一起进步