一、力扣
1、基本计算器 II


每遇到一个运算符,已经在栈中存放前两个数字,preSign是前一个运算符,计算后存入栈中。
java
class Solution {
public int calculate(String s) {
ArrayDeque<Integer> stack=new ArrayDeque<>();
int pre=0;
char preSign='+';
for(int i=0;i<s.length();i++){
char ans=s.charAt(i);
if(Character.isDigit(ans)){
pre=pre*10+ans-'0';
}
if(!Character.isDigit(ans)&&ans!=' '||i==s.length()-1){
if(preSign=='+'){
stack.push(pre);
}else if(preSign=='-'){
stack.push(-pre);
}else if(preSign=='*'){
stack.push(stack.pop()*pre);
}else{
stack.push(stack.pop()/pre);
}
pre=0;
preSign=s.charAt(i);
}
}
int res=0;
while(!stack.isEmpty()){
res+=stack.pop();
}
return res;
}
}
2、 基本计算器

因为没有乘除,遇到括号就存放当前运算符,遇到数字就计算当前数字,因为当前数字不会影响以后。
java
class Solution {
public int calculate(String s) {
ArrayDeque<Integer> stack=new ArrayDeque<>();
int sign=1;
stack.push(1);
int res=0;
for(int i=0;i<s.length();){
char e=s.charAt(i);
if(e==' '){
i++;
}else if(e=='+'){
sign=stack.peek();
i++;
}else if(e=='-'){
sign=-stack.peek();
i++;
}else if(e=='('){
stack.push(sign);
i++;
}else if(e==')'){
stack.pop();
i++;
}else{
int ans=0;
while(i<s.length()&&Character.isDigit(s.charAt(i))){
ans=ans*10+s.charAt(i)-'0';
i++;
}
res=res+sign*ans;
}
}
return res;
}
}
3、单词拆分

java
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
int maxLen = 0;
for (String word : wordDict) {
maxLen = Math.max(maxLen, word.length());
}
Set<String> words = new HashSet<>(wordDict);
int n = s.length();
boolean[] f = new boolean[n + 1];
f[0] = true;
for (int i = 1; i <= n; i++) {
for (int j = i - 1; j >= Math.max(i - maxLen, 0); j--) {
if (f[j] && words.contains(s.substring(j, i))) {
f[i] = true;
break;
}
}
}
return f[n];
}
}
4、两两交换链表中的节点

java
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummy=new ListNode(0);
dummy.next=head;
ListNode fir=head;
ListNode pre=dummy;
while(fir!=null&&fir.next!=null){
ListNode sec=fir.next;
ListNode nextfir=sec.next;
ListNode nextpre=fir;
pre.next=sec;
sec.next=fir;
fir.next=nextfir;
fir=nextfir;
pre=nextpre;
}
return dummy.next;
}
}
5、单调递增的数字

java
class Solution {
public int monotoneIncreasingDigits(int n) {
// 将数字转换为字符数组以便逐位处理
char[] ans = Integer.toString(n).toCharArray();
int len = ans.length;
int point = 1; // 从第二位开始检查递增性
// 寻找第一个不满足递增条件的位置
while (point < len && ans[point - 1] <= ans[point]) {
point++;
}
// 如果存在不满足条件的位置
if (point < len) {
// 回溯调整,确保高位递减后重新满足递增
while (point > 0 && ans[point - 1] > ans[point]) {
ans[point - 1] -= 1; // 前一位减1
point--; // 向前检查是否仍需调整
}
// 将后续所有位设为9,确保最大值
for (int i = point + 1; i < len; i++) {
ans[i] = '9';
}
}
// 转换回整数并返回
return Integer.parseInt(new String(ans));
}
}
6、小于n的最大数
题目描述: 数组A中给定可以使用的1~9的数,返回由A数组中的元素组成的小于n(n > 0)的最大数。例如:A = {1, 2, 4, 9},n = 2533,返回2499。
测试用例:
java
A = {1, 2, 4, 9}
n = 2533
输出 = 2499
A = {4, 2, 9, 8}
n = 988822
输出 = 988499
A = {9, 8}
n = 9
输出 = 8
A = {9, 6, 3, 5}
n = 56449
输出 = 56399
思路: 实际上数只有十个,那我们贪心就好了,我们首先匹配这个数 ,如果每一位都在这个数组中存在,就修改最小的一位,如果不就把最高的不能匹配的位之后变成数组中最大值,这一位找一个小的数代替
java
public class MainTest {
static char[] target;
static int[] cur;
static long res = 0;
public static long atMostNGivenDigitSet(String[] digits, int n) {
target = Integer.toString(n).toCharArray();
cur = new int[digits.length];
for (int i = 0; i < digits.length; i++) {
cur[i] = Integer.parseInt(digits[i]);
}
Arrays.sort(cur);
res = 0;// 对数组进行排序
dfs(0, true, false, 0L);
return res;
}
public static void dfs(int start, boolean isHigh, boolean isNum, long ans) {
if (start == target.length) {
if (isNum) {
res = Math.max(res, ans);
}
return;
}
// 不选择当前位,继续递归
if (!isNum) {
dfs(start + 1, false, false, ans);
}
// 选择当前位
int max = isHigh ? (target[start] - '0') : 9;
for (int e : cur) {
if (e > max) continue;
dfs(start + 1, isHigh && (e == max), true, ans * 10 + e);
}
}
public static void main(String[] args) {
System.out.println(atMostNGivenDigitSet(new String[]{"1", "2", "4", "9"}, 2533));
System.out.println(atMostNGivenDigitSet(new String[]{"4", "2", "9", "8"}, 988822));
System.out.println(atMostNGivenDigitSet(new String[]{"9", "8"}, 8));
System.out.println(atMostNGivenDigitSet(new String[]{"9", "6", "3", "5"}, 56449));
System.out.println(atMostNGivenDigitSet(new String[]{"1","2","3","4","5","6","7","8"}, 8363065));
System.out.println(atMostNGivenDigitSet(new String[]{"1","2","3","4","5","6","7","8","9"}, 8363065));
}
}
7、数位dp-最大为 N 的数字组合

java
class Solution {
char[] target;
int[] cur;
public int atMostNGivenDigitSet(String[] digits, int n) {
target = Integer.toString(n).toCharArray();
cur = new int[digits.length];
for (int i = 0; i < digits.length; i++) {
cur[i] = Integer.parseInt(digits[i]);
}
int[] memo = new int[target.length + 1];
Arrays.fill(memo, -1);
return dfs(0, true, false, memo);
}
public int dfs(int start, boolean isHigh, boolean isNum, int[] memo) {
if (start == target.length) {
return isNum ? 1 : 0;
}
if (!isHigh && isNum && memo[start] >= 0) {
return memo[start];
}
int res = 0;
if (!isNum) {
res += dfs(start + 1, false, false, memo);
}
int max = isHigh ? target[start] - '0' : 9;
for (var e : cur) {
if (e > max) break;
res += dfs(start + 1, isHigh && e == target[start] - '0', true, memo);
}
if (!isHigh && isNum) {
memo[start] = res;
}
return res;
}
}
8、二叉树展开为链表

java
class Solution {
TreeNode las=null;
public void flatten(TreeNode root) {
dfs(root);
}
public void dfs(TreeNode root){
if(root==null) return;
dfs(root.right);
dfs(root.left);
root.left=null;
root.right=las;
las=root;
}
}