2. Add Two Numbers
题目:将两个整数反序存入链表,计算两者之和并反序存入链表,返回头结点。
思路:设置flag作为进位标志,按位计算和值,存入返回链表。对还有剩余的链表,按照之前的方法继续存入。需要注意,最后的标志位不要漏掉。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode p=new ListNode(0);
ListNode head=p;
boolean flag=false;
while(l1!=null&&l2!=null){
int x=l1.val+l2.val+(flag?1:0);
if(x>9){
flag=true;
p.next=new ListNode(x-10);
}
else{
flag=false;
p.next=new ListNode(x);
}
p=p.next;
l1=l1.next;
l2=l2.next;
}
while(l1!=null){
int x=l1.val+(flag?1:0);
if(x>9){
flag=true;
p.next=new ListNode(x-10);
}
else{
flag=false;
p.next=new ListNode(x);
}
p=p.next;
l1=l1.next;
}
while(l2!=null){
int x=l2.val+(flag?1:0);
if(x>9){
flag=true;
p.next=new ListNode(x-10);
}
else{
flag=false;
p.next=new ListNode(x);
}
p=p.next;
l2=l2.next;
}
if(flag){
p.next=new ListNode(1);
}
return head.next;
}
}
看了下其他人的代码,将三个while循环合并,内部处理有优化,并且看起来比较美观。但是运行时间看上去没有很大区别。
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode p1 = l1;
ListNode p2 = l2;
ListNode head = new ListNode(0);
ListNode q = head;
int sum = 0;
while(p1!=null || p2!=null){
sum /= 10;
if(p1!=null){
sum += p1.val;
p1 = p1.next;
}
if(p2!=null){
sum += p2.val;
p2 = p2.next;
}
q.next = new ListNode(sum%10);
q=q.next;
}
if((sum/10)==1){
q.next = new ListNode(1);
}
return head.next;
}
}
445. Add Two Numbers II
题目:整数正序怎么办?要求输出也正序。
思路:栈——尝试用栈,显示内存溢出。第二次写通过了!!!what???黑人问号……区别是第一次用的size判断栈是否为空,第二次用的isEmpty判断。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
Stack<Integer> s1 = new Stack<>();
Stack<Integer> s2 = new Stack<>();
Stack<Integer> s = new Stack<>();
ListNode p1 = l1;
ListNode p2 = l2;
ListNode head = new ListNode(0);
ListNode q = head;
while(p1!=null){
s1.push(p1.val);
p1 = p1.next;
}
while(p2!=null){
s2.push(p2.val);
p2 = p2.next;
}
int sum = 0;
while(!s1.isEmpty() || !s2.isEmpty()){
sum /= 10;
if(!s1.isEmpty()){
sum += s1.pop();
}
if(!s2.isEmpty()){
sum += s2.pop();
}
s.push(sum%10);
}
if(sum/10 == 1){
s.push(1);
}
while(!s.isEmpty()){
q.next = new ListNode(s.pop());
q = q.next;
}
return head.next;
}
}
371. Sum of Two Integers
题目:计算两整数之和,不允许使用+和-
思路:位运算——这种类型一般GG,看了其他人的解法,感觉很巧妙,总结的也很全面。基本想法是:利用按位与&结果得到进位值,再利用按位异或^结果得到直接没有进位相加的结果,然后进位结果每次左移与之前相加的结果继续相加,循环直到移位结果为零。两数相减同理,相减结果异或^得到,借位结果需要找出被减数0减数1的位置,这里对被减数取反,然后和减数按位与&得到。
public class Solution {
public int getSum(int a, int b) {
int x = a;
int y = b;
int carry = 0;
while(y!=0){
carry = x & y;
x = x ^ y;
y = carry << 1;
}
return x;
}
}
67. Add Binary
题目:输入为两个二进制字符串,计算两者之和,以二进制字符串形式输出。
思路:类似2——本来想用位运算来做,但怎样都超出范围,所以只能通过字符串按位计算得到,这里只是把10进制换成二进制,思路完全一样。
public class Solution {
public String addBinary(String a, String b) {
int x = a.length()-1, y = b.length()-1;
StringBuffer sb = new StringBuffer();
int sum = 0;
while(x >= 0 || y >= 0){
sum /= 2;
if(x >= 0){
if(a.charAt(x) == '1') sum += 1;
}
if(y >= 0){
if(b.charAt(y) == '1') sum += 1;
}
sb.append(sum%2);
x--;
y--;
}
if(sum/2 == 1) sb.append(1);
return sb.reverse().toString();
}
}
415. Add Strings
题目:用字符串表示两个非负整数,计算两者之和,并用字符串输出。
思路:与67题完全一样,区别只在这里变成十进制,字符串转成整数的地方不同。
public class Solution {
public String addStrings(String num1, String num2) {
int a = num1.length()-1, b = num2.length()-1;
StringBuffer sb = new StringBuffer();
int sum = 0;
while(a >= 0 || b >= 0){
sum /= 10;
if(a >= 0){
sum += num1.charAt(a) - '0';
}
if(b >= 0){
sum += num2.charAt(b) - '0';
}
sb.append(sum%10);
a--;
b--;
}
if(sum/10 == 1){
sb.append(1);
}
return sb.reverse().toString();
}
}
题目:用字符串表示两个非负整数,计算两者乘积,并以字符串输出。
思路:充分理解乘法计算的具体过程。eg:a*b,分解成乘数a的第i位与乘数b的第j位相乘,十位对应到最后结果的第i+j位,个位对应到最后结果的第i+j+1位,这里需要注意要在原来对应结果的基础上加。另外,前导零不能输出也是需要注意的地方,一要主要,前导零不止一个,二要注意结果为零的情况。
public class Solution {
public String multiply(String num1, String num2) {
int a = num1.length(), b = num2.length();
int[] cal = new int[a+b];
for(int i = a-1; i >= 0; i--){
for(int j = b-1; j >= 0; j--){
int mul = (num1.charAt(i) - '0')*(num2.charAt(j) - '0');
int pos1 = i+j, pos2 = i+j+1;
int sum = mul + cal[pos1]*10 + cal[pos2];
cal[pos1] = sum/10;
cal[pos2] = sum%10;
}
}
StringBuffer sb = new StringBuffer();
int i = 0;
while(i < cal.length && cal[i] == 0) i++;
for(; i < a+b-1; i++){
sb.append(cal[i]);
}
sb.append(cal[a+b-1]);
return sb.toString();
}
}
题目:计算非负整数+1。
思路:也采取了按位向前加的方式。
public class Solution {
public int[] plusOne(int[] digits) {
int len = digits.length;
int sum = digits[len-1] +1;
digits[len-1] = sum%10;
for(int i = len-2; i >= 0; i--){
sum = sum/10;
if(sum == 1){
sum = digits[i]+1;
digits[i] = sum%10;
}
else{
break;
}
}
if(sum == 10){
int[] ret = new int[len+1];
for(int i = 1; i < len+1; i++){
ret[i] = digits[i-1];
}
ret[0] = 1;
return ret;
}
return digits;
}
}