title: 2022-08-21-1455-检查单词是否为句中其他单词的前缀
date: 2022-08-21 15:01:12
tags: [Daily Practice, 简单题, 字符串, 双指针, 模拟]
categories: 算法题
class Solution {
public int isPrefixOfWord(String sentence, String searchWord) {
// 切割成单词
String [] ch = sentence.split(" ");
for (int i = 0; i < ch.length; i++) {
if (isqz(searchWord, ch[i])) {
return i + 1;
}
}
return -1;
}
// 判断A是否为a的前缀
public boolean isqz(String a, String A) {
int la = a.length(), lA = A.length();
if (la > lA) {
return false;
}
for (int i = 0; i < la; i++) {
if (a.charAt(i) != A.charAt(i)) {
return false;
}
}
return true;
}
}
/**
* @param {string} sentence
* @param {string} searchWord
* @return {number}
*/
var isPrefixOfWord = function(sentence, searchWord) {
// 切割成单词
let ch = sentence.split(" ");
for (let i = 0; i < ch.length; i++) {
if (isqz(searchWord, ch[i])) {
return i + 1;
}
}
return -1;
};
// 判断A是否为a的前缀
const isqz = function (a, A) {
let la = a.length, lA = A.length;
if (la > lA) {
return false;
}
for (let i = 0; i < la; i++) {
if (a.charAt(i) !== A.charAt(i)) {
return false;
}
}
return true;
}
class Solution {
public int isPrefixOfWord(String sentence, String searchWord) {
int n = sentence.length(), index = 1, start = 0, end = 0;
while (start < n) {
while (end < n && sentence.charAt(end) != ' ') {
end++;
}
if (isPrefix(sentence, start, end, searchWord)) {
return index;
}
index++;
end++;
start = end;
}
return -1;
}
public boolean isPrefix(String sentence, int start, int end, String searchWord) {
for (int i = 0; i < searchWord.length(); i++) {
if (start + i >= end || sentence.charAt(start + i) != searchWord.charAt(i)) {
return false;
}
}
return true;
}
}
var isPrefixOfWord = function(sentence, searchWord) {
let n = sentence.length, index = 1, start = 0, end = 0;
while (start < n) {
while (end < n && sentence[end] !== ' ') {
end++;
}
if (isPrefix(sentence, start, end, searchWord)) {
return index;
}
index++;
end++;
start = end;
}
return -1;
}
const isPrefix = (sentence, start, end, searchWord) => {
for (let i = 0; i < searchWord.length; i++) {
if (start + i >= end || sentence[start + i] !== searchWord[i]) {
return false;
}
}
return true;
};
title: 2022-08-22-655-输出二叉树
date: 2022-08-22 19:01:12
tags: [Daily Practice, 中等题, dfs]
categories: 算法题
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private List<List<String>> ans;
private int height;
public List<List<String>> printTree(TreeNode root) {
height = dfs1(root);
ans = new ArrayList<>(height);
int n = (1 << height) - 1;
for (int i = 0; i < height; i++) {
List<String> list = new ArrayList<>(n);
for (int j = 0; j < n; j++) {
list.add("");
}
ans.add(list);
}
dfs2(root, 0, (n - 1) >> 1);
return ans;
}
private int dfs1(TreeNode node) {
return node != null ? Math.max(dfs1(node.left), dfs1(node.right)) + 1 : 0;
}
private void dfs2(TreeNode node, int r, int c) {
ans.get(r).set(c, node.val + "");
int diff = 1 << height - 2 - r;
if (node.left != null) {
dfs2(node.left, r + 1, c - diff);
}
if (node.right != null) {
dfs2(node.right, r + 1, c + diff);
}
}
}
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {string[][]}
*/
var printTree = function(root) {
const calDepth = (root) => {
let h = 0;
if (root.left) {
h = Math.max(h, calDepth(root.left) + 1);
}
if (root.right) {
h = Math.max(h, calDepth(root.right) + 1);
}
return h;
}
const dfs = (res, root, r, c, height) => {
res[r][c] = root.val.toString();
if (root.left) {
dfs(res, root.left, r + 1, c - (1 << (height - r - 1)), height);
}
if (root.right) {
dfs(res, root.right, r + 1, c + (1 << (height - r - 1)), height);
}
}
const height = calDepth(root);
const m = height + 1;
const n = (1 << (height + 1)) - 1;
const res = new Array(m).fill(0).map(() => new Array(n).fill(''));
dfs(res, root, 0, Math.floor((n - 1) / 2), height);
return res;
};
title: 2022-08-23-782-变为棋盘
date: 2022-08-23 22:01:12
tags: [Daily Practice, 困难题]
categories: 算法题
class Solution {
public int movesToChessboard(int[][] board) {
int n = board.length;
int rowMask = 0, colMask = 0;
/* 检查棋盘的第一行与第一列 */
for (int i = 0; i < n; i++) {
rowMask |= (board[0][i] << i);
colMask |= (board[i][0] << i);
}
int reverseRowMask = ((1 << n) - 1) ^ rowMask;
int reverseColMask = ((1 << n) - 1) ^ colMask;
int rowCnt = 0, colCnt = 0;
for (int i = 0; i < n; i++) {
int currRowMask = 0;
int currColMask = 0;
for (int j = 0; j < n; j++) {
currRowMask |= (board[i][j] << j);
currColMask |= (board[j][i] << j);
}
/* 检测每一行的状态是否合法 */
if (currRowMask != rowMask && currRowMask != reverseRowMask) {
return -1;
} else if (currRowMask == rowMask) {
/* 记录与第一行相同的行数 */
rowCnt++;
}
/* 检测每一列的状态是否合法 */
if (currColMask != colMask && currColMask != reverseColMask) {
return -1;
} else if (currColMask == colMask) {
/* 记录与第一列相同的列数 */
colCnt++;
}
}
int rowMoves = getMoves(rowMask, rowCnt, n);
int colMoves = getMoves(colMask, colCnt, n);
return (rowMoves == -1 || colMoves == -1) ? -1 : (rowMoves + colMoves);
}
public int getMoves(int mask, int count, int n) {
int ones = Integer.bitCount(mask);
if ((n & 1) == 1) {
/* 如果 n 为奇数,则每一行中 1 与 0 的数目相差为 1,且满足相邻行交替 */
if (Math.abs(n - 2 * ones) != 1 || Math.abs(n - 2 * count) != 1 ) {
return -1;
}
if (ones == (n >> 1)) {
/* 以 0 为开头的最小交换次数 */
return n / 2 - Integer.bitCount(mask & 0xAAAAAAAA);
} else {
return (n + 1) / 2 - Integer.bitCount(mask & 0x55555555);
}
} else {
/* 如果 n 为偶数,则每一行中 1 与 0 的数目相等,且满足相邻行交替 */
if (ones != (n >> 1) || count != (n >> 1)) {
return -1;
}
/* 找到行的最小交换次数 */
int count0 = n / 2 - Integer.bitCount(mask & 0xAAAAAAAA);
int count1 = n / 2 - Integer.bitCount(mask & 0x55555555);
return Math.min(count0, count1);
}
}
}
title: 2022-08-24-1460-通过翻转子数组使两个数组相等
date: 2022-08-24 19:01:12
tags: [Daily Practice, 简单题]
categories: 算法题
class Solution {
public boolean canBeEqual(int[] target, int[] arr) {
Arrays.sort(target);
Arrays.sort(arr);
return Arrays.equals(target, arr);
}
}
var canBeEqual = function(target, arr) {
target.sort((a, b) => a - b);
arr.sort((a, b) => a - b);
return target.toString() === arr.toString();
};
class Solution {
public boolean canBeEqual(int[] target, int[] arr) {
Map<Integer, Integer> counts1 = new HashMap<Integer, Integer>();
Map<Integer, Integer> counts2 = new HashMap<Integer, Integer>();
for (int num : target) {
counts1.put(num, counts1.getOrDefault(num, 0) + 1);
}
for (int num : arr) {
counts2.put(num, counts2.getOrDefault(num, 0) + 1);
}
if (counts1.size() != counts2.size()) {
return false;
}
for (Map.Entry<Integer, Integer> entry : counts1.entrySet()) {
int key = entry.getKey(), value = entry.getValue();
if (!counts2.containsKey(key) || counts2.get(key) != value) {
return false;
}
}
return true;
}
}
var canBeEqual = function(target, arr) {
const counts1 = new Map();
const counts2 = new Map();
for (const num of target) {
counts1.set(num, (counts1.get(num) || 0) + 1);
}
for (const num of arr) {
counts2.set(num, (counts2.get(num) || 0) + 1);
}
if (counts1.size !== counts2.size) {
return false;
}
for (const [key, value] of counts1.entries()) {
if (!counts2.has(key) || counts2.get(key) !== value) {
return false;
}
}
return true;
};
title: 2022-08-25-658-找到 K 个最接近的元素
date: 2022-08-25 23:01:12
tags: [Daily Practice, 中等题, 二分, 排序]
categories: 算法题
直接按照要求做差并排序再比较选取
class Solution {
public List<Integer> findClosestElements(int[] arr, int k, int x) {
List<Integer> list = new ArrayList<Integer>();
for (int num : arr) {
list.add(num);
}
Collections.sort(list, (a, b) -> {
if (Math.abs(a - x) != Math.abs(b - x)) {
return Math.abs(a - x) - Math.abs(b - x);
} else {
return a - b;
}
});
List<Integer> ans = list.subList(0, k);
Collections.sort(ans);
return ans;
}
}
var findClosestElements = function(arr, k, x) {
const list = [...arr];
list.sort((a, b) => {
if (Math.abs(a - x) !== Math.abs(b - x)) {
return Math.abs(a - x) - Math.abs(b - x);
} else {
return a - b;
}
});
const ans = list.slice(0, k);
ans.sort((a, b) => a - b);
return ans;
};
class Solution {
public List<Integer> findClosestElements(int[] arr, int k, int x) {
int right = binarySearch(arr, x);
int left = right - 1;
while (k-- > 0) {
if (left < 0) {
right++;
} else if (right >= arr.length) {
left--;
} else if (x - arr[left] <= arr[right] - x) {
left--;
} else {
right++;
}
}
List<Integer> ans = new ArrayList<Integer>();
for (int i = left + 1; i < right; i++) {
ans.add(arr[i]);
}
return ans;
}
public int binarySearch(int[] arr, int x) {
int low = 0, high = arr.length - 1;
while (low < high) {
int mid = low + (high - low) / 2;
if (arr[mid] >= x) {
high = mid;
} else {
low = mid + 1;
}
}
return low;
}
}
var findClosestElements = function(arr, k, x) {
let right = binarySearch(arr, x);
let left = right - 1;
while (k-- > 0) {
if (left < 0) {
right++;
} else if (right >= arr.length) {
left--;
} else if (x - arr[left] <= arr[right] - x) {
left--;
} else {
right++;
}
}
const ans = [];
for (let i = left + 1; i < right; i++) {
ans.push(arr[i]);
}
return ans;
}
const binarySearch = (arr, x) => {
let low = 0, high = arr.length - 1;
while (low < high) {
const mid = low + Math.floor((high - low) / 2);
if (arr[mid] >= x) {
high = mid;
} else {
low = mid + 1;
}
}
return low;
}
title: 2022-08-26-1464-数组中两元素的最大乘积
date: 2022-08-26 18:01:12
tags: [Daily Practice, 简单题, 排序]
categories: 算法题
class Solution {
public int maxProduct(int[] nums) {
int len = nums.length;
Arrays.sort(nums);
return (nums[len - 1] - 1) * (nums[len - 2] - 1);
}
}
/**
* @param {number[]} nums
* @return {number}
*/
var maxProduct = function(nums) {
let len = nums.length;
nums.sort((a, b) => a - b);
return (nums[len - 1] - 1) * (nums[len - 2] - 1);
};
// 官解
var maxProduct = function(nums) {
nums.sort((a, b) => a - b);
console.log(nums)
return (nums[nums.length - 1] - 1) * (nums[nums.length - 2] - 1);
};
class Solution {
public int maxProduct(int[] nums) {
int a = nums[0], b = nums[1];
if (a < b) {
int temp = a;
a = b;
b = temp;
}
for (int i = 2; i < nums.length; i++) {
if (nums[i] > a) {
b = a;
a = nums[i];
} else if (nums[i] > b) {
b = nums[i];
}
}
return (a - 1) * (b - 1);
}
}
var maxProduct = function(nums) {
let a = nums[0], b = nums[1];
if (a < b) {
const temp = a;
a = b;
b = temp;
}
for (let i = 2; i < nums.length; i++) {
if (nums[i] > a) {
b = a;
a = nums[i];
} else if (nums[i] > b) {
b = nums[i];
}
}
return (a - 1) * (b - 1);
};
title: 2022-08-27-662-二叉树最大宽度
date: 2022-08-27 13:01:12
tags: [Daily Practice, 中等题, 二叉树, dfs, bfs]
categories: 算法题
class Solution {
public int widthOfBinaryTree(TreeNode root) {
int res = 1;
List<Pair<TreeNode, Integer>> arr = new ArrayList<Pair<TreeNode, Integer>>();
arr.add(new Pair<TreeNode, Integer>(root, 1));
while (!arr.isEmpty()) {
List<Pair<TreeNode, Integer>> tmp = new ArrayList<Pair<TreeNode, Integer>>();
for (Pair<TreeNode, Integer> pair : arr) {
TreeNode node = pair.getKey();
int index = pair.getValue();
if (node.left != null) {
tmp.add(new Pair<TreeNode, Integer>(node.left, index * 2));
}
if (node.right != null) {
tmp.add(new Pair<TreeNode, Integer>(node.right, index * 2 + 1));
}
}
res = Math.max(res, arr.get(arr.size() - 1).getValue() - arr.get(0).getValue() + 1);
arr = tmp;
}
return res;
}
}
class Solution {
Map<Integer, Integer> levelMin = new HashMap<Integer, Integer>();
public int widthOfBinaryTree(TreeNode root) {
return dfs(root, 1, 1);
}
public int dfs(TreeNode node, int depth, int index) {
if (node == null) {
return 0;
}
levelMin.putIfAbsent(depth, index); // 每一层最先访问到的节点会是最左边的节点,即每一层编号的最小值
return Math.max(index - levelMin.get(depth) + 1, Math.max(dfs(node.left, depth + 1, index * 2), dfs(node.right, depth + 1, index * 2 + 1)));
}
}
var widthOfBinaryTree = function(root) {
/** JS 存在计数溢出的问题,使用 BigInt,BigInt 不能调用 Math 中的方法。 */
let maxWidth = 1n;
const leftIds = []
const dfs = (root, level, currIdx) => {
if (leftIds[level] === undefined) {
leftIds[level] = currIdx;
} else {
const width = currIdx - leftIds[level] + 1n;
maxWidth = maxWidth > width ? maxWidth : width;
}
if (root.left !== null) {
dfs(root.left, level + 1, currIdx * 2n - 1n);
}
if (root.right !== null) {
dfs(root.right, level + 1, currIdx * 2n);
}
}
dfs(root, 0, 1n);
return maxWidth;
};
title: 2022-08-28-793-阶乘函数后K个零
date: 2022-08-28 13:01:12
tags: [Daily Practice, 困难题, 数学, 二分]
categories: 算法题
// 数学
class Solution {
public int preimageSizeFZF(int k) {
//确定阶梯值范围 最终的到的K < start
int start = 1;
while (start < K){
start = start * 5+1;
}
//确定范围后,执行精确查找
while (start > 1){
//只有5以下阶乘才会出现start-1成立,其它情况不会存在,因为任何一个阶段分界值都会包含一个以上的5
if(start - 1 == K){
//不存在的返回0
return 0;
}
//逆推下一个阶梯值 从f(x+1) 推导出f(x)
start = (start - 1) / 5;
//获取剩余值,进行下一阶梯运算
K %= start;
}
//只要存在,必然是5个
return 5;
}
}
// 递归 + 二分
class Solution {
public int preimageSizeFZF(int k) {
long l = k - 1,r = k * 10L + 1;
while(l + 1 < r){
long m = l + r >> 1,t = f(m);
if(t == k) return 5;
else if(t < k) l = m;
else r = m;
}
return 0;
}
long f(long n){
if(n == 0) return 0;
return n / 5 + f(n / 5);
}
}
// 三叶 数学 + 二分
class Solution {
public int preimageSizeFZF(int k) {
if (k <= 1) return 5;
return f(k) - f(k - 1);
}
int f(int x) {
long l = 0, r = (long) 1e10;
while (l < r) {
long mid = l + r + 1 >> 1;
if (getCnt(mid) <= x) l = mid;
else r = mid - 1;
}
return (int)r;
}
long getCnt(long x) {
long ans = 0;
while (x != 0) {
ans += x / 5; x /= 5;
}
return ans;
}
}
var preimageSizeFZF = function(k) {
return help(k + 1) - help(k);
}
const help = (k) => {
let r = 5 * k;
let l = 0;
while (l <= r) {
const mid = Math.floor((l + r) / 2);
if (zeta(mid) < k) {
l = mid + 1;
} else {
r = mid - 1;
}
}
return r + 1;
}
const zeta = (x) => {
let res = 0;
while (x != 0) {
res += Math.floor(x / 5);
x = Math.floor(x / 5);
}
return res;
};
title: 2022-08-29-1470-重新排列数组
date: 2022-08-29 9:01:12
tags: [Daily Practice, 简单题, 模拟]
categories: 算法题
class Solution {
public int[] shuffle(int[] nums, int n) {
int [] cnt = new int[2 * n];
for (int i = 0, j = 0; i < 2 * n; i++, j++) {
cnt[i++] = nums[j];
cnt[i] = nums[j + n];
}
return cnt;
}
}
// 官解
class Solution {
public int[] shuffle(int[] nums, int n) {
int[] ans = new int[2 * n];
for (int i = 0; i < n; i++) {
ans[2 * i] = nums[i];
ans[2 * i + 1] = nums[i + n];
}
return ans;
}
}
var shuffle = function(nums, n) {
var cnt = new Array(2 * n).fill(0);
for (let i = 0, j = 0; i < 2 * n; i++, j++) {
cnt[i++] = nums[j];
cnt[i] = nums[j + n];
}
return cnt;
};
// 官解
var shuffle = function(nums, n) {
const ans = new Array(2 * n).fill(0);
for (let i = 0; i < n; i++) {
ans[2 * i] = nums[i];
ans[2 * i + 1] = nums[i + n];
}
return ans;
};
title: 2022-08-30-998-最大二叉树 II
date: 2022-08-30 22:01:12
tags: [Daily Practice, 中等题, 二叉树]
categories: 算法题
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode insertIntoMaxTree(TreeNode root, int val) {
TreeNode parent = null;
TreeNode cur = root;
while (cur != null) {
if (val > cur.val) {
if (parent == null) {
return new TreeNode(val, root, null);
}
TreeNode node = new TreeNode(val, cur, null);
parent.right = node;
return root;
} else {
parent = cur;
cur = cur.right;
}
}
parent.right = new TreeNode(val);
return root;
}
}
var insertIntoMaxTree = function(root, val) {
let parent = null;
let cur = root;
while (cur) {
if (val > cur.val) {
if (!parent) {
return new TreeNode(val, root, null);
}
let node = new TreeNode(val, cur, null);
parent.right = node;
return root;
} else {
parent = cur;
cur = cur.right;
}
}
parent.right = new TreeNode(val);
return root;
};
title: 2022-08-30-946-验证栈序列
date: 2022-08-31 15:01:12
tags: [Daily Practice, 中等题, 栈, 模拟]
categories: 算法题
class Solution {
public boolean validateStackSequences(int[] pushed, int[] popped) {
Deque<Integer> stack = new ArrayDeque<>();
int j = 0; //索引popped
for (int i = 0; i < pushed.length; i++) {
stack.push(pushed[i]);
while (!stack.isEmpty() && stack.peek() == popped[j]) {
j++;
stack.pop();
}
}
return stack.isEmpty();
}
}
/**
* @param {number[]} pushed
* @param {number[]} popped
* @return {boolean}
*/
var validateStackSequences = function(pushed, popped) {
let stack = [];
let j = 0;
for (let i = 0, l = pushed.length; i < l; i++) {
stack.push(pushed[i]);
while (stack.length != 0 && stack[stack.length - 1] == popped[j]) {
j++;
stack.pop();
}
}
return stack.length === 0;
};
class Solution {
public boolean validateStackSequences(int[] pushed, int[] popped) {
int n = pushed.length, idx = 0;
for (int i = 0, j = 0; i < n; i++) {
pushed[idx++] = pushed[i];
while (idx > 0 && pushed[idx - 1] == popped[j] && ++j >= 0) idx--;
}
return idx == 0;
}
}
/**
* @param {number[]} pushed
* @param {number[]} popped
* @return {boolean}
*/
var validateStackSequences = function(pushed, popped) {
let n = pushed.length, idx = 0;
for (let i = 0, j = 0; i < n; i++) {
pushed[idx++] = pushed[i];
while (idx > 0 && pushed[idx - 1] == popped[j] && ++j >= 0) idx--;
}
return idx == 0;
};