逆序处理首先应该想到栈!!!
1、此题的难点就是如何找到目标倒数节点的前驱结点
在遍历链表的同时将所有节点依次入栈。根据**栈「先进后出」**的原则,我们弹出栈的第 nn 个节点就是需要删除的节点,并且目前栈顶的节点就是待删除节点的前驱节点。这样一来,删除操作就变得十分方便了。
2、本题的主要难点在于链表中数位的顺序与我们做加法的顺序是相反的,为了逆序处理所有数位,我们可以使用栈:把所有数字压入栈中,再依次取出相加。计算过程中需要注意进位的情况。
栈
本题的主要难点在于链表中数位的顺序与我们做加法的顺序是相反的,为了逆序处理所有数位,我们可以使用栈:把所有数字压入栈中,再依次取出相加。计算过程中需要注意进位的情况。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
//数据需要逆序处理应该首先想到用栈(先进后出)!!!
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//创建两个栈分别用于处理两个链表节点的值
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
//压栈
while(null != l1){
stack1.push(l1.val);
l1 = l1.next;
}
while(null != l2){
stack2.push(l2.val);
l2 = l2.next;
}
//计数位(满10进1)
int carry = 0;
//用于存储结果的新链表
ListNode ans = null;
//出栈
while(!stack1.empty() || !stack2.empty() || carry > 0){
int sum = carry;
sum += stack1.empty() ? 0 : stack1.pop();
sum += stack2.empty() ? 0 : stack2.pop();
carry = sum / 10;
//使用头插法(每次插入的新节点都在头结点之后,已有节点之前),后序不需要再反转一次链表了
ListNode cur = new ListNode(sum % 10);
cur.next = ans;
ans = cur;
}
return ans;
}
}
注意:头插法的使用( 观察两种写法的细微差别,两者空间使用不同)
一
ListNode ans = null;
ListNode cur = new ListNode(sum % 10);
cur.next = ans;
ans = cur;
return ans;
二
ListNode ans = new ListNode(-1);
ListNode cur = new ListNode(sum % 10);
cur.next = ans;
ans = cur;
return ans.next;
二分查找算法的两种实现方式(递归与非递归)
**//二分查找递归写法**
public boolean binary_search(long start, long end, int target) {
if (start > end)
return false;
long middle = start + (end - start) / 2;
if (middle * middle == target)
return true;
if (middle * middle > target)
return binary_search(start, middle - 1, target);
return binary_search(middle + 1, ende, target);
}
**//二分查找非递归写法(迭代)**
public boolean binary_search(long start, long end, int target){
while(start <= end){
long middle = start + (end - start) / 2;
if(middle * middle == target){
return true;
}else if(middle * middle < target){
start = middle + 1;
}else{
end = middle - 1;
}
}
return false;
}
判断回文数
public boolean isPalindrome(char[] str, int start, int end){
int i = start;
int j = end;
//不要惯性思维,写成int i = 0; int j = str.length - 1;
while(i <= j){
if(str[i] != str[j]){
return false;
}else{
i++;
j--;
}
}
return true;
}