文章目录
C# 写多了,写Java反而有点不适应了,比如C#的是string,还有方法名首字母大写…
3/4/2022
1. 子数组范围和
法1:暴力遍历
public long subArrayRanges(int[] nums) {
long res = 0;
for (int i = 0; i < nums.length; i++) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int j = i; j < nums.length; j++) {
min = Math.min(nums[j], min);
max = Math.max(nums[j], max);
res += max - min;
}
}
return res;
}
法2:单调栈
这道题理解成求子数组的最大值之和-子数组的最小值之和
public long subArrayRanges(int[] nums) {
Deque<Integer> minDeque = new LinkedList<>();
Deque<Integer> maxDeque = new LinkedList<>();
long minSum = 0;
long maxSum = 0;
int[] ns = new int[nums.length + 2];
System.arraycopy(nums, 0, ns, 1, nums.length);
ns[0] = Integer.MIN_VALUE;
ns[ns.length - 1] = Integer.MIN_VALUE;
for (int i = 0; i < ns.length; i++) {
while (!minDeque.isEmpty() && ns[i] < ns[minDeque.peekLast()]) {
int idx = minDeque.pollLast();
minSum += (long) (i - idx) * (idx - minDeque.peekLast()) * ns[idx];
}
minDeque.offerLast(i);
}
ns[0] = Integer.MAX_VALUE;
ns[ns.length - 1] = Integer.MAX_VALUE;
for (int i = 0; i < ns.length; i++) {
while (!maxDeque.isEmpty() && ns[i] > ns[maxDeque.peekLast()]) {
int idx = maxDeque.pollLast();
maxSum += (long) (i - idx) * (idx - maxDeque.peekLast()) * ns[idx];
}
maxDeque.offerLast(i);
}
return maxSum - minSum;
}
3/6/2022
1. 子数组的最小值之和
public int sumSubarrayMins(int[] arr) {
int[] nums = new int[arr.length + 2];
System.arraycopy(arr, 0, nums, 1, arr.length);
Deque<Integer> deque = new LinkedList<>();
long res = 0;
for (int i = 0; i < nums.length; i++) {
while (!deque.isEmpty() && nums[i] < nums[deque.peekLast()]) {
int idx = deque.pollLast();
res += (long) (i - idx) * (idx - deque.peekLast()) * nums[idx];
res %= 1000000007;
}
deque.offerLast(i);
}
return (int) (res);
}
3/19/2022
1. 二进制求和
没想到这道题面试做的好烂…其实跟十进制的加法几乎一样的处理
public String addBinary(String a, String b) {
StringBuilder sb = new StringBuilder();
int m = a.length();
int n = b.length();
int carry = 0;
for (int i = 0; i < m || i < n; i++) {
int num1 = i < m ? (a.charAt(m - i - 1) - '0') : 0;
int num2 = i < n ? (b.charAt(n - i - 1) - '0') : 0;
int sum = num1 + num2 + carry;
carry = sum / 2;
sb.append(String.valueOf(sum % 2));
}
if (carry > 0) {
sb.append('1');
}
sb.reverse();
return sb.toString();
}
2. 字符串相乘
public String multiply(String num1, String num2) {
if (num1.equals("0") || num2.equals("0")) {
return "0";
}
String sum = "0";
int m = num1.length();
int n = num2.length();
String[] nums = new String[m];
for (int i = 0; i < m; i++) {
StringBuilder sb = new StringBuilder();
int carry = 0;
for (int j = 0; j < n; j++) {
int a = num1.charAt(m - i - 1) - '0';
int b = num2.charAt(n - j - 1) - '0';
int product = a * b + carry;
carry = product / 10;
sb.append(product % 10);
}
if (carry > 0) {
sb.append(carry + "");
}
sb.reverse();
for (int k = 0; k < i; k++) {
sb.append('0');
}
nums[i] = sb.toString();
sum = add(sum, nums[i]);
}
return String.valueOf(sum);
}
public String add(String a, String b) {
StringBuilder sb = new StringBuilder();
int m = a.length();
int n = b.length();
int carry = 0;
for (int i = 0; i < m || i < n; i++) {
int num1 = i < m ? (a.charAt(m - i - 1) - '0') : 0;
int num2 = i < n ? (b.charAt(n - i - 1) - '0') : 0;
int sum = num1 + num2 + carry;
carry = sum / 10;
sb.append(String.valueOf(sum % 10));
}
if (carry > 0) {
sb.append(carry + "");
}
sb.reverse();
return sb.toString();
}
3. 两整数之和
public int getSum(int a, int b) {
while (b != 0) {
int carry = (a & b) << 1;
a = a ^ b;
b = carry;
}
return a;
}
4. 字符串相加
public String addStrings(String num1, String num2) {
StringBuilder sb = new StringBuilder();
int m = num1.length();
int n = num2.length();
int carry = 0;
for (int i = 0; i < m || i < n; i++) {
int a = i < m ? (num1.charAt(m - i - 1) - '0') : 0;
int b = i < n ? (num2.charAt(n - i - 1) - '0') : 0;
int sum = a + b + carry;
carry = sum / 10;
sb.append(String.valueOf(sum % 10));
}
if (carry > 0) {
sb.append(carry + "");
}
sb.reverse();
return sb.toString();
}
3/20/2022
1. 加一
public int[] plusOne(int[] digits) {
int n = digits.length;
for (int i = 0; i < n; i++) {
digits[n - i - 1]++;
digits[n - i - 1] %= 10;
if (digits[n - i - 1] != 0) {
return digits;
}
}
int[] ans = new int[n + 1];
ans[0] = 1;
return ans;
}
2. 数组形式的整数加法
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> ans = new ArrayList<>();
int n = num.length;
int carry = 0;
for (int i = 0; i < n || k != 0; i++) {
int a = i < n ? num[n - i - 1] : 0;
int b = k % 10;
int sum = a + b + carry;
k /= 10;
carry = sum / 10;
ans.add(sum % 10);
}
if (carry > 0) {
ans.add(1);
}
Collections.reverse(ans);
return ans;
}
3/21/2022
1. 两数之和 IV - 输入 BST
public boolean findTarget(TreeNode root, int k) {
Set<Integer> set = new HashSet<>();
boolean ans = preOrder(root, k, set);
return ans;
}
public boolean preOrder(TreeNode root, int k, Set<Integer> set) {
if (root == null) {
return false;
}
if (set.contains(k - root.val)) {
return true;
}
set.add(root.val);
return preOrder(root.left, k, set) || preOrder(root.right, k, set);
}
3/22/2022
1. 罗马数字转整数
public int romanToInt(String s) {
Map<Character, Integer> map = new HashMap<>() {{
put('I', 1);
put('V', 5);
put('X', 10);
put('L', 50);
put('C', 100);
put('D', 500);
put('M', 1000);
}};
int ans = 0;
int n = s.length();
for (int i = 0; i < n; i++) {
if (i == n - 1) {
ans += map.get(s.charAt(i));
} else if (map.get(s.charAt(i)) >= map.get(s.charAt(i + 1))) {
ans += map.get(s.charAt(i));
} else {
ans -= map.get(s.charAt(i));
}
}
return ans;
}
4/6/2022
1. 整数转罗马数字
public String intToRoman(int num) {
int[] nums = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
String[] romans = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
StringBuilder sb = new StringBuilder();
for (int i = 0; i < nums.length; i++) {
while (num >= nums[i]) {
sb.append(romans[i]);
num -= nums[i];
}
}
return sb.toString();
}
4/7/2022
1. 多数元素
public int majorityElement(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
if (map.get(nums[i]) > nums.length / 2) {
return nums[i];
}
}
return 0;
}
4/8/2022
1. 求众数 II
public List<Integer> majorityElement(int[] nums) {
List<Integer> ans = new ArrayList<>();
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
if (map.get(nums[i]) > nums.length / 3) {
if (!ans.contains(nums[i])) {
ans.add(nums[i]);
}
}
}
return ans;
}
4/10/2022
1. 最后一个单词的长度
法1:
public int lengthOfLastWord(String s) {
String[] strs = s.split(" ");
return strs[strs.length - 1].length();
}
法2:
public int lengthOfLastWord(String s) {
s = s.trim();
int idx = s.length() - 1;
int ans = 0;
while (idx >= 0 && s.charAt(idx) != ' ') {
ans++;
idx--;
}
return ans;
}