给定两个链表的头节点head1和head2,
认为从左到右是某个数字从低位到高位,返回相加之后的链表
例子 4 -> 3 -> 6 2 -> 5 -> 3
返回 6 -> 8 -> 9
解释 634 + 352 = 986
/*
* 两个链表相加
* 给定两个链表的头节点head1和head2,
认为从左到右是某个数字从低位到高位,返回相加之后的链表
例子 4 -> 3 -> 6 2 -> 5 -> 3
返回 6 -> 8 -> 9
解释 634 + 352 = 986
* */
public class AddTwoNumbers {
public static class ListNode {
public int val;
public ListNode next;
public ListNode(int val) {
this.val = val;
}
public ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
/*
* 思路:1:找到长链表L,短链表S
* 2:划分成3个阶段,阶段1:长链表L,短链表S都有,阶段2:长链表L有,短链表S无,阶段3:长链表L无,短链表S无
* 3:注意进位,不额外开辟空间,直接将相加的结果放到长链表L上。
* */
public static ListNode addTwoNumbers(ListNode head1, ListNode head2) {
// 标注长短链表
ListNode L = listLength(head1) > listLength(head2) ? head1 : head2;
ListNode S = L == head1 ? head2 : head1;
// 标注当前链表的指向节点
ListNode curL = L;
ListNode curS = S;
// 进位
int carry = 0;
// 当前长节点要填的数
int curNuber = 0;
// 一直记录着长链表的尾节点,用于连接第三阶段的节点
ListNode last = L;
// 第一阶段:长链表L,短链表S都有
while(curS != null) {
int curNum = curL.val + curS.val + carry;
carry = curNum / 10;
curNuber = curNum % 10;
curL.val = curNuber;
last = curL;
curL = curL.next;
curS = curS.next;
}
// 第二阶段:长链表L有,短链表S无
while(curL != null) {
int curNum = curL.val + carry;
carry = curNum / 10;
curNuber = curNum % 10;
curL.val = curNuber;
last = curL;
curL = curL.next;
}
// 第三阶段
if(carry == 1) {
ListNode node = new ListNode(1);
last.next = node;
}
return L;
}
// 计算链表的长度
public static int listLength(ListNode head) {
if (head == null) {
return 0;
}
int count = 0;
while(head != null) {
count++;
head = head.next;
}
return count;
}
}
public class BitMap {
private long[] bits;
public BitMap(int max) {
// max + 64 -> 当max == 63时,我们需要1个空间,当max == 0时我们需要1个空间
bits = new long[(max + 64) >> 6];
}
public void add(int num) {
/*
// 属于哪个数组的下标
int flg1 = num >> 6;
// 属于当前数组下标下的哪个位置
int flg2 = num & 63;
bits[flg1] = (1L << flg2) | bits[flg1];
*/
bits[num >> 6] |= (1L << (num & 63));
}
public void delete(int num) {
/**
* int flg1 = num >> 6;
* int flg2 = num & 63;
* bits[flg1] = bits[flg1] & ~(1L << flg2);
*/
bits[num >> 6] &= ~(1L << (num & 63));
}
public boolean contains(int num) {
return (bits[num >> 6] & (1L << (num & 63))) != 0;
}
}
加法运算 -> 无进位相加的信息(异或运算) + 进位信息(与运算)
a + b 可以不断的向下转化成无进位加信息+进位信息,但底层并没有加号这一说法(我们无法直接进行相加),所以我们需要一直往下进行转换直至进位信息是0的时候,我们得到的无进位加信息就是我们的答案。
// 用位运算实现 + - * /
public class BitAddMinusMultiDiv {
public static int add(int a, int b) {
int sum = a;
while(b != 0) {
sum = a ^ b; // 无进位相加信息
b = (a & b) << 1; // 进位信心
a = sum;
}
return sum;
}
// 判断是否是负数
public static boolean isNeg(int n) {
return n < 0;
}
// 取相反数
public static int negNum(int n) {
return add((~n),1);
}
// 减法就相当于:加一个相反数
public static int minus(int a, int b) {
return add(a,negNum(b));
}
// 乘法
public static int multi(int a, int b) {
int sum = 0;
while(b != 0) {
if((b & 1) != 0) {
sum = add(sum , a);
}
b >>>= 1;
a <<= 1;
}
return sum;
}
public static int div(int a, int b) {
int x = isNeg(a) ? negNum(a) : a;
int y = isNeg(b) ? negNum(b) : b;
// x / y
int ans = 0;
for (int i = 30; i >= 0; i--) {
if((x >> i) >= y) {
ans |= (1 << i);
x = minus(x,y << i);
}
}
return isNeg(a) != isNeg(b) ? negNum(ans) : ans;
}
public static int divide(int a, int b) {
if(a == Integer.MIN_VALUE && b == Integer.MIN_VALUE) {
return 1;
}else if(b == Integer.MIN_VALUE) {
return 0;
}else if(a == Integer.MIN_VALUE) {
if(b == negNum(1)) {
return Integer.MAX_VALUE;
}else {
/*
* c = (a + 1) / b
* d = a - b * c
* e = d / b
* return e + c
* */
int c = div(add(a , 1), b);
return add(c , div(minus(a,multi(b,c)),b));
}
}else {
return div(a , b);
}
}
}
public static int multi(int a, int b) {
int sum = 0;
while(b != 0) {
if((b & 1) != 0) {
sum = add(sum , a);
}
b >>>= 1;
a <<= 1;
}
return sum;
}
public static int div(int a, int b) {
// 将负数全部转化成正数,这样好分析
int x = isNeg(a) ? negNum(a) : a;
int y = isNeg(b) ? negNum(b) : b;
// x / y
int ans = 0;
for (int i = 30; i >= 0; i--) {
if((x >> i) >= y) {
ans |= (1 << i);
x = minus(x,y << i);
}
}
return isNeg(a) != isNeg(b) ? negNum(ans) : ans;
}
public static int divide(int a, int b) {
if(a == Integer.MIN_VALUE && b == Integer.MIN_VALUE) {
return 1;
}else if(b == Integer.MIN_VALUE) {
return 0;
}else if(a == Integer.MIN_VALUE) {
if(b == negNum(1)) {
return Integer.MAX_VALUE;
}else {
/*
* c = (a + 1) / b
* d = a - b * c
* e = d / b
* return e + c
* */
int c = div(add(a , 1), b);
return add(c , div(minus(a,multi(b,c)),b));
}
}else {
return div(a , b);
}
}