2. 两数相加
解法
- 这个题目做了无数遍了,是能够确定掌握的题目之一。
- 要注意两点:一是判空,因为两个链表长度不一,二是,要注意进位。
复杂度:时间O(n) | 空间O(1)
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode x1 = l1;
ListNode x2 = l2;
int mod = 0;
ListNode l3 = new ListNode();
ListNode head = l3;
while (x1 != null || x2 != null || mod != 0) {
int val1 = x1 == null ? 0 : x1.val;
int val2 = x2 == null ? 0 : x2.val;
int sum = val1 + val2 + mod;
l3.next = new ListNode(sum % 10);
mod = (sum) / 10;
if (x1 != null) {
x1 = x1.next;
}
if (x2 != null) {
x2 = x2.next;
}
l3 = l3.next;
}
return head.next;
}
}
206. 反转链表
解法
递归和顺序的都要掌握。
(1)迭代
必然要用到多指针。
复杂度:时间O(n) | 空间O(1)
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode p, q, r;
p = null;
q = head;
r = q.next;
while (q != null) {
// 反转,因为每次只走一步,所以,每次只做一次反转动作
q.next = p;
// 让指针往前走
p = q;
q = r;
if (r != null) {
r = r.next;
}
}
return p;
}
}
(2)递归
递归反正每次都写不出来。
复杂度:时间O(n) | 空间O(n),因为栈需要存储元素。
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;
}
}
445. 两数相加 II
和第一题差不多,区别在于第一题是逆序,这一题是正序。
解法
先将两个链表翻转,再相加合并,然后再翻转返回。
复杂度:时间O(n) | 空间O(m+n)
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode x1 = reverseList(l1);
ListNode x2 = reverseList(l2);
return reverseList(addTwoNums(x1, x2));
}
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;
}
public ListNode addTwoNums(ListNode l1, ListNode l2) {
ListNode x1 = l1;
ListNode x2 = l2;
int mod = 0;
ListNode l3 = new ListNode();
ListNode head = l3;
while (x1 != null || x2 != null || mod != 0) {
int val1 = x1 == null ? 0 : x1.val;
int val2 = x2 == null ? 0 : x2.val;
int sum = val1 + val2 + mod;
l3.next = new ListNode(sum % 10);
mod = (sum) / 10;
if (x1 != null) {
x1 = x1.next;
}
if (x2 != null) {
x2 = x2.next;
}
l3 = l3.next;
}
return head.next;
}
}
989. 数组形式的整数加法
解法
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> result = new LinkedList<>();
int len = num.length;
for (int i = len - 1; i >= 0; i--) {
int sum = num[i] + k % 10;
k /= 10;
if (sum >= 10) {
k++;
sum = sum % 10;
}
result.addFirst(sum);
}
for (; k > 0; k = k / 10) {
result.addFirst(k % 10);
}
return result;
}
}
这个应该是数字运算进位的常用思路,要记住的。 直接用k个num里的每一位相加,然后取余留给当前位置,除10给进位。
class Solution {
public List<Integer> addToArrayForm(int[] num, int k) {
List<Integer> result = new LinkedList<>();
int len = num.length;
for (int i = len - 1; i >= 0 || k > 0; i--, k = k / 10) {
if (i >= 0) {
k = k + num[i];
}
result.addFirst(k % 10);
}
return result;
}
}
344. 反转字符串
要求必须原地翻转,只可以使用O(1)的空间
解法
太简单了,不提。
class Solution {
public void reverseString(char[] s) {
int left = 0;
int right = s.length - 1;
while (left < right) {
swap(s, left++, right--);
}
}
public void swap(char[] s, int left, int right) {
char tmp = s[left];
s[left] = s[right];
s[right] = tmp;
}
}
415. 字符串相加
字符串反转,可以使用StringBuilder
class Solution {
public String addStrings(String num1, String num2) {
int len1 = num1.length();
int len2 = num2.length();
int l1 = len1 - 1;
int l2 = len2 - 1;
int mod = 0;
StringBuilder result = new StringBuilder();
while (l1 >= 0 || l2 >= 0 || mod > 0) {
int v1 = l1 >= 0 ? num1.charAt(l1) - '0' : 0;
int v2 = l2 >= 0 ? num2.charAt(l2) - '0' : 0;
int sum = v1 + v2 + mod;
mod = sum / 10;
if (sum >= 10) {
sum %= 10;
}
result.append(sum);
l1--;
l2--;
}
result.reverse();
return result.toString();
}
}
43. 字符串相乘
解法
- 直接用乘法运算。计算每一位之间的乘积,将结果相加,放入数组中。
- 得到的乘积最多为
m+n位。
class Solution {
public String multiply(String num1, String num2) {
if (num1.equals("0") || num2.equals("0")) {
return "0";
}
int m = num1.length();
int n = num2.length();
int[] result = new int[m + n];
for (int i = m - 1; i >= 0; i--) {
int v1 = num1.charAt(i) - '0';
for (int j = n - 1; j >= 0; j--) {
int v2 = num2.charAt(j) - '0';
result[i + j + 1] += v1 * v2;
}
}
for (int k = m + n - 1; k > 0; k--) {
int val = result[k];
result[k] = val % 10;
result[k - 1] += val / 10;
}
int index = result[0] == 0 ? 1 : 0;
StringBuilder sb = new StringBuilder();
while (index < m + n) {
sb.append(result[index++]);
}
return sb.toString();
}
}
67. 二进制求和
解法
也是很简单,十进制转化为二进制运算就行了。
class Solution {
public String addBinary(String a, String b) {
int m = a.length() - 1;
int n = b.length() - 1;
int mod = 0;
StringBuilder sb = new StringBuilder();
while (m >= 0 || n >= 0 || mod != 0) {
int val1 = m >= 0 ? a.charAt(m) - '0' : 0;
int val2 = n >= 0 ? b.charAt(n) - '0' : 0;
int sum = val1 + val2 + mod;
mod = sum / 2;
if (sum == 2) {
sb.append("0");
} else if (sum == 3) {
sb.append("1");
} else {
sb.append(sum);
}
m--;
n--;
}
sb.reverse();
return sb.toString();
}
}