class CQueue {
//输入队列
private Stack<Integer> stack1 = new Stack<Integer>();
//输出队列
private Stack<Integer> stack2 = new Stack<Integer>();
public CQueue() {
}
public void appendTail(int value) {
stack1.push(value);
}
public int deleteHead() {
int result = -1;
//判断输出栈是否为空,非空将输出栈的一个元素抛出
if(!stack2.empty()){
result = stack2.pop();
}else{
//此时输出栈为空,将输入栈内容输出到输出栈
this.output();
if(!stack2.empty()){
result = stack2.pop();
}
}
return result;
}
public void output(){
while(!stack1.empty()){
stack2.push(stack1.pop());
}
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public void deleteNode(ListNode node) {
node.val = node.next.val;
node.next = node.next.next;
}
}
尝试了
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public void deleteNode(ListNode node) {
node = node.next;
}
}
发现没法通过,图解如下(遍历结点时用的是next,但是next实则没有改变)
class Solution {
public int[] spiralOrder(int[][] matrix) {
int length = 0;
int[] arr;
try{
length = matrix.length * matrix[0].length;
}catch(ArrayIndexOutOfBoundsException e){
return arr = new int[0];
}
arr = new int[length];
int k = 0;
for (int i = 0; k<length; ++i) {
//上层,为了使得奇数时中心点可以输出,应该范围是i~atrix.length - 1 - i
for (int j = i; (j <= matrix[0].length - 1 - i) && (k<length); ++j) {
arr[k++]=matrix[i][j];
}
//右层
for (int j = i+1; (j <= matrix.length - 2 - i) && (k<length); ++j) {
arr[k++]=matrix[j][matrix[0].length - 1 - i];
}
//下层
for (int j = matrix[0].length - 1 - i; (j >= i + 1) && (k<length); --j) {
arr[k++]=matrix[matrix.length - 1 - i][j];
}
//左层
for (int j = matrix.length - 1 - i; (j >= i + 1) && (k<length); --j) {
arr[k++]=matrix[j][i];
}
}
return arr;
}
}
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
int length = 0;
List list = new ArrayList();
try{
length = matrix.length * matrix[0].length;
}catch(ArrayIndexOutOfBoundsException e){
return list;
}
int k = 0;
for (int i = 0; k<length; ++i) {
//上层,为了使得奇数时中心点可以输出,应该范围是i~atrix.length - 1 - i
for (int j = i; (j <= matrix[0].length - 1 - i) && (k<length); ++j) {
list.add(matrix[i][j]);
++k;
}
//右层
for (int j = i+1; (j <= matrix.length - 2 - i) && (k<length); ++j) {
list.add(matrix[j][matrix[0].length - 1 - i]);
++k;
}
//下层
for (int j = matrix[0].length - 1 - i; (j >= i + 1) && (k<length); --j) {
list.add(matrix[matrix.length - 1 - i][j]);
++k;
}
//左层
for (int j = matrix.length - 1 - i; (j >= i + 1) && (k<length); --j) {
list.add(matrix[j][i]);
++k;
}
}
return list;
}
}
int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
class Solution {
public int[] spiralOrder(int[][] matrix) {
if(matrix.length == 0) return new int[0];
int l = 0, r = matrix[0].length - 1, t = 0, b = matrix.length - 1, x = 0;
int[] res = new int[(r + 1) * (b + 1)];
while(true) {
for(int i = l; i <= r; i++) res[x++] = matrix[t][i]; // left to right.
if(++t > b) break;
for(int i = t; i <= b; i++) res[x++] = matrix[i][r]; // top to bottom.
if(l > --r) break;
for(int i = r; i >= l; i--) res[x++] = matrix[b][i]; // right to left.
if(t > --b) break;
for(int i = b; i >= t; i--) res[x++] = matrix[i][l]; // bottom to top.
if(++l > r) break;
}
return res;
}
}
作者:jyd
链接:https://leetcode-cn.com/problems/shun-shi-zhen-da-yin-ju-zhen-lcof/solution/mian-shi-ti-29-shun-shi-zhen-da-yin-ju-zhen-she-di/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public int findLength(int[] A, int[] B) {
//dp代表以第i个元素和第j个元素结尾的连续子数组的最大长度
int[][] dp = new int[A.length+1][B.length+1];
int max = 0;
for(int i = 0; i <= A.length; i++){
for(int j = 0; j <= B.length; j++){
if(i == 0 || j == 0){
dp[i][j] = 0;
continue;
}else{
//dp中的i和j应该代表数组第几个,对应的数组下标应该是减1
if(A[i-1] == B[j-1]){
dp[i][j] = dp[i-1][j-1] + 1;
}else{
dp[i][j] = 0;
}
max = Math.max(max,dp[i][j]);
}
}
}
return max;
}
}
class Solution {
public int numWays(int n) {
int num = 0;
int[] dp = new int[101];
dp[0] = 1;
dp[1] = 1;
for(int i=2; i<=n; ++i){
dp[i] = (dp[i-1] + dp[i-2])%1000000007;
}
return dp[n];
}
}
class Solution {
public int waysToStep(int n) {
long[] dp = new long[n+1];
dp[0] = 1;
if(n>=1){dp[1] = 1;}
if(n>=2){dp[2] = 2;}
for(int i=3; i<=n; ++i){
dp[i] = (dp[i-1] + dp[i-2] + dp[i-3])%1000000007;
}
return (int)dp[n];
}
}
class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs.length == 0){
return "";
}
StringBuffer comPre = new StringBuffer("");
char temp;
//找到最小的字符串长度
int length = 100000;
for (int i = 0; i < strs.length; ++i){
length = (length > strs[i].length()) ? strs[i].length() : length;
}
//从第一个字符串找第i个字符,与字符数组其他的第i个字符比较
for(int i=0; i<length; ++i){
int tag = 1;
temp = strs[0].charAt(i);
//第j个字符串的第i个字符与第一个字符串中找到第i个字符不相等,循环结束
for(int j =1; j<strs.length;++j){
if(temp != strs[j].charAt(i)){
tag = 0;
break;
}
}
if(tag==1){
comPre.append(temp);
}else{
break;
}
}
//StringBuffer的toString方法可以转成String
return comPre.toString();
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode rotateRight(ListNode head, int k) {
//对传入的链表为空以及k为0的处理
if(head == null || k == 0){
return head;
}
//求链表长度
int length = 0;
ListNode pNode = head;
//最后结点
ListNode pEnd = null;
//旋转后的新首结点
ListNode pNewHead = null;
while(pNode!=null){
length++;
if(pNode.next==null){
//说明是最后一个结点
pEnd = pNode;
break;
}
pNode = pNode.next;
}
//如果k大于链表的长度则取模
if(k>=length){
k = k%length;
}
if(k == 0){
return head;
}
//找到第length-k个结点,将他的下一个结点赋值给pNewHead,然后将其next变为null
pNode = head;
int count = 1;
while(true){
if(count == (length - k)){
break;
}
++count;
pNode = pNode.next;
}
//此时的pNode为第length-k个结点
pNewHead = pNode.next;
pNode.next = null;
pEnd.next = head;
return pNewHead;
}
}
class Solution {
public int myAtoi(String str) {
//对空字符串处理,返回0代表无法处理
if(str == null ){
return 0;
}
//temp用于存储数字
StringBuffer temp = new StringBuffer("");
//symbol用于存储符号,默认为正
char symbol = '+';
//将字符串首尾的空格去除,并验证此时的str是否为""
str = str.trim();
if("".equals(str)){
return 0;
}
//对字符串第一个字符的处理
char First = str.charAt(0);
if(First=='+' || First=='-' ){
symbol = First;
}else if(First>=48 && First<=57){
temp.append(First);
}else{
//字符此时非正负号和数字
return 0;
}
char t;
for(int i=1;i<str.length();++i){
t = str.charAt(i);
if(t>=48 && t<=57){
temp.append(t);
}else {
//此时非数字,结束循环
break;
}
}
str = temp.toString();
//验证此时的str是否为"",输入为"+"时会出现这种情况
if("".equals(str)){
return 0;
}
//将字符前缀为0的部分去除,即找到第一个不为0的字符
int i = 0;
while(i<str.length()&&str.charAt(i)==48){
++i;
}
if(i<str.length()){
str = str.substring(i);
}else{
//证明str全为0
return 0;
}
int result = 0;
//Integer会不会溢出问题
if(str.length()>10){
//溢出
if(symbol == '-'){
result = -2147483648;
}else{
result = 2147483647;
}
}else if(str.length()<10){
//肯定没溢出
if(symbol == '-'){
result = Integer.valueOf("-"+str);
}else{
result = Integer.valueOf(str);
}
}else {
//数字位数为10,使用字典序的比较方式
if(symbol == '-'){
if(str.compareTo("2147483648")>0){
//溢出
result = -2147483648;
}else {
result = Integer.valueOf("-"+str);
}
}else{
if(str.compareTo("2147483647")>0){
//溢出
result = 2147483647;
}else {
result = Integer.valueOf(str);
}
}
}
return result;
}
}
public class Solution {
public int myAtoi(String str) {
char[] chars = str.toCharArray();
int n = chars.length;
int idx = 0;
while (idx < n && chars[idx] == ' ') {
// 去掉前导空格
idx++;
}
if (idx == n) {
//去掉前导空格以后到了末尾了
return 0;
}
boolean negative = false;
if (chars[idx] == '-') {
//遇到负号
negative = true;
idx++;
} else if (chars[idx] == '+') {
// 遇到正号
idx++;
} else if (!Character.isDigit(chars[idx])) {
// 其他符号
return 0;
}
int ans = 0;
while (idx < n && Character.isDigit(chars[idx])) {
int digit = chars[idx] - '0';
if (ans > (Integer.MAX_VALUE - digit) / 10) {
// 本来应该是 ans * 10 + digit > Integer.MAX_VALUE
// 但是 *10 和 + digit 都有可能越界,所有都移动到右边去就可以了。
return negative? Integer.MIN_VALUE : Integer.MAX_VALUE;
}
ans = ans * 10 + digit;
idx++;
}
return negative? -ans : ans;
}
}
class Solution {
class Automaton {
final String START = "start";
final String SIGNED = "signed";
final String IN_NUM = "in_number";
final String END = "end";
String state = START;
Map<String, String[]> map;
public int sign = 1;
public long ans = 0;
public Automaton() {
map = new HashMap<>();
map.put(START, new String[]{START, SIGNED, IN_NUM, END});
map.put(SIGNED, new String[]{END, END, IN_NUM, END});
map.put(IN_NUM, new String[]{END, END, IN_NUM, END});
map.put(END, new String[]{END, END, END, END});
}
public int get_col(char c) {
if (c == ' ') return 0;
if (c == '+' || c == '-') return 1;
if (c >= '0' && c <= '9') return 2;
return 3;
}
public void get(char c) {
state = map.get(state)[get_col(c)];
if (state.equals(IN_NUM)) {
ans = ans * 10 + c - '0';
if (sign == 1) {
ans = Math.min(ans, Integer.MAX_VALUE);
} else {
// -(long)Integer.MIN_VALUE,这个操作有点东西,不然越界
ans = Math.min(ans, -(long)Integer.MIN_VALUE);
}
} else if (state.equals(SIGNED))
sign = c == '+' ? 1 : -1;
}
}
public int myAtoi(String str) {
Automaton automaton = new Automaton();
char[] c = str.toCharArray();
for (char ch : c) {
automaton.get(ch);
}
return automaton.sign * ((int) automaton.ans);
}
}
class Solution {
public int kthSmallest(int[][] matrix, int k) {
int[] arr = insertSort(matrix);
return arr[k-1];
}
//定义一个插入排序算法,将矩阵转为n*n长度的一维数组
public int[] insertSort(int[][] matrix){
int length = matrix.length;
int temp;
int[] arr = new int[length*length];
for(int i=0; i<length; ++i){
for(int j=0; j<length; ++j){
temp = matrix[i][j];
//插入的是第i*length+j个
//找到按序插入的位置t
int t = i*length+j;
while(t>0 && arr[t-1]>temp){
//右移
arr[t] = arr[t-1];
t--;
}
arr[t] = temp;
}
}
return arr;
}
}
class Solution {
public int reverse(int x) {
int result = 0;
if(x>=0){
while(x!=0){
if((2147483647-x%10)/10>=result){
result = x%10+result*10;
x/=10;
}else {
//溢出
result = 0;
break;
}
}
}else{
if(x==-2147483648){
return 0;
}
int x1 = -x;
while(x1!=0){
if((2147483648L-x1%10)/10>=result){
result = x1%10+result*10;
x1/=10;
}else {
//溢出
result = 0;
break;
}
}
result = (-1)*result;
}
return result;
}
}
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
//排序
Arrays.sort(nums);
//使用暴力解法
List<List<Integer>> list1 = new ArrayList<>() ;
List<Integer> list;
int n = nums.length;
int target;
for(int i = 0; (i<nums.length-2);++i){
//从第二个开始时要找到与之前枚举过的不同的第一个元素
if(i>0&& nums[i-1]==nums[i]){
continue;
}
target = -nums[i];
//k代表第三个元素位置
int k = n-1;
for (int j = i+1;(j<nums.length-1);++j){
//找到没有枚举过的第二元素
if(j>i+1 && nums[j-1]==nums[j]){
continue;
}
while(j<k && nums[j]+nums[k]>target){
--k;
}
if(j==k){
break;
}
if(nums[j]+nums[k]==target){
list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[k]);
list1.add(list);
}
//执行到这为找不到与第二个元素匹配的第三元素,此时枚举的第二元素排除符合条件可能
}
}
return list1;
}
}
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//对传入的链为空的处理
//设置保留进位和剩余位,和
int carry = 0,remain,sum;
//设置两个链头指向两链表
ListNode pNode1 = l1;
ListNode pNode2 = l2;
//设置两个链指向两链表的前一个结点
ListNode preNode1 = null;
ListNode preNode2 = null;
while (pNode1 != null && pNode2 != null){
sum = pNode1.val + pNode2.val+carry;
remain = sum%10;
carry = sum/10;
//保留l1作为新链
pNode1.val = remain;
//更新链的指向
preNode1 = pNode1;
pNode2 = pNode2.next;
pNode1 = pNode1.next;
}
if(pNode1 == null && pNode2 != null){
preNode1.next = pNode2;
pNode1 = pNode2;
//更新pNode1的所有结点在接收进位后的变化
while(carry>0 && pNode1 != null){
sum = pNode1.val + carry;
pNode1.val = sum%10;
carry = sum/10;
preNode1= pNode1;
pNode1 = pNode1.next;
}
if(pNode1 == null && carry>0){
preNode1.next = new ListNode(carry);
}
}
if(pNode2 == null && pNode1 != null){
//更新pNode1的所有结点在接收进位后的变化
while(carry>0 && pNode1 != null){
sum = pNode1.val + carry;
pNode1.val = sum%10;
carry = sum/10;
preNode1= pNode1;
pNode1 = pNode1.next;
}
if(pNode1 == null && carry>0){
preNode1.next = new ListNode(carry);
}
}
if(pNode1 == null && pNode2 == null && carry>0){
preNode1.next = new ListNode(carry);
}
return l1;
}
}
改进点,循环条件改为pNode1 == null || pNode2 != null,null的设为0
class Solution {
public String longestPalindrome(String s) {
if("".equals(s) || s==null){
return s;
}
//标记数组tag【长度,起始下标,结束下标】,用于记录找到的回文子串
int[] tag = {0,0,0};
//遍历所有的元素
First:for(int i = 0; i < s.length(); ++i){
//找到与首元素相同的下标,可能有机会为回文子串
for(int j=s.length()-1; (j > i) ;--j){
if(s.charAt(i) != s.charAt(j)){
continue ;
}
if((j-i+1) <= tag[0]){
//如果找到可能为回文子串的长度小于已经找到的最大长度的回文子串
// 那么内层循环找不到比已经找到的最大长度的回文子串还大的子串,回到外层循环
continue First;
}
//判断是否为回文子串
Boolean flag = true;//默认为回文子串
int head = i+1;
int tail = j-1;
while((tail - head)>=1){
if(s.charAt(head) != s.charAt(tail)){
flag = false;
break ;
}
++head;
--tail;
}
if(flag){
tag[0] = j-i+1;
tag[1] = i;
tag[2] = j;
}
}
}
//substring取不到结束下标的字符
return s.substring(tag[1],tag[2]+1);
}
}
动态规划
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
if(nums.length == 0){
return null;
}
//寻找中间结点
int mid = nums.length/2;
TreeNode treeNode = new TreeNode(nums[mid]);
//初始化左子树对应的一维数组
int[] leftArr = new int[mid];
for(int i = 0;i<mid;++i){
leftArr[i] = nums[i];
}
//初始化右子树对应的一维数组
int[] rightArr = new int[nums.length-mid-1];
for(int i = 0;i<nums.length-mid-1;++i){
rightArr[i] = nums[i+mid+1];
}
treeNode.left = sortedArrayToBST(leftArr);
treeNode.right = sortedArrayToBST(rightArr);
return treeNode;
}
}
class Solution {
public int search(int[] nums, int target) {
//使用折半查找
//nums = [4,5,6,7,0,1,2], target = 0,
int left = 0;
int right = nums.length-1;
int mid = (left + right)/2;
while(left < right){
if(nums[mid]>=nums[left]){
if(target<=nums[mid] && target >=nums[left]){
right = mid;
mid = (left + right)/2;
}else{
left = mid + 1;
mid = (left + right)/2;
}
}else {
if(target<=nums[mid] || target >=nums[left]){
right = mid;
mid = (left + right)/2;
}else {
left = mid + 1;
mid = (left + right)/2;
}
}
}
if(left == right && nums[right] == target){
return left;
}else {
return -1;
}
}
}
class Solution {
public boolean isPowerOfTwo(int n) {
//对于整数小于等于0的判断
if(n <= 0){
return false;
}
boolean flag = true;
while(n != 1){
if(n%2 == 0){
n/=2;
}else{
flag = false;
break;
}
}
return flag;
}
}
位运算 判断条件 (x & (-x)) == x
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
//使用插入的方法
//定义一个tail作为num1中第一个为空的下标
int tail = m;
//定义一个保持需要插入的位置
int insertPos;
int etem;
for(int i = 0; i < n; ++i){
etem = nums2[i];
insertPos = tail;
while(insertPos >= 1 && nums1[insertPos-1] > etem){
nums1[insertPos] = nums1[insertPos-1];
--insertPos;
}
nums1[insertPos] = etem;
//插入完毕后tail后移动一位
++tail;
}
}
}
class Solution {
public boolean isPalindrome(int x) {
if(x < 0){
return false;
}
return reverse(x) == x;
}
public int reverse(int x){
int rev = 0;
while(x != 0){
rev = x % 10 + rev * 10;
x /= 10;
}
return rev;
}
}
class Solution {
public void reverseString(char[] s) {
int head = 0;
int tail = s.length-1;
char temp;
while(tail - head >= 1){
temp = s[head];
s[head] = s[tail];
s[tail] = temp;
++head;
--tail;
}
}
}
class Solution {
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null){
//说明为最后一个链结点
return head;
}
//使用递归的方法反转链表
ListNode newHead = reverseList(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
}
class Solution {
public int maxProfit(int[] prices) {
// 1.找到数组持续下降的地点---买入点
// 2.找到数组持续上升的高点---卖出点
// 重复1和2知道数组结束
int lowpoint;
int highPoint;
int maxProfit = 0;
for (int i = 0; i < prices.length; ++i) {
while (i < prices.length - 1 && prices[i] >= prices[i + 1]) {
/*找到数组持续下降的地点---买入点*/
++i;
}
if (i == prices.length) {
break;
} else {
lowpoint = prices[i];
++i;
}
while (i < prices.length - 1 && prices[i] <= prices[i + 1]) {
/*找到数组持续上升的高点---卖出点*/
++i;
}
if (i == prices.length) {
break;
} else {
highPoint = prices[i];
}
maxProfit = maxProfit + highPoint - lowpoint;
}
return maxProfit;
}
}
class Solution {
public List<Integer> list = new ArrayList<>(1);
public List<List<Integer>> lists = new ArrayList<>();
int f = 0;
public List<List<Integer>> permute(int[] nums) {
if (nums == null) {
return null;
}
if (nums.length == 1) {
//坑人的点,list由于是同个所以,会随着set变化而变化
if (list.size() == 0) {
list.add(0);
}
list.set(f, nums[0]);
List<Integer> temp = new ArrayList<>();
for (Integer i : list) {
temp.add(i);
}
lists.add(temp);
return lists;
}
for (int i = 0; i < nums.length; ++i) {
if (f == 0) {
list = new ArrayList<>(nums.length);
for (int t = 0; t < nums.length; ++t) {
list.add(0);
}
}
list.set(f++, nums[i]);
int[] arr = new int[nums.length - 1];
int k = 0;
for (int j = 0; j < nums.length; ++j) {
if (i != j) {
arr[k++] = nums[j];
}
}
permute(arr);
--f;
}
return lists;
}
}
class Solution {
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
if (root.left == null && root.right == null) {
return 1;
} else {
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
}
}