力扣专题—数学
定义
采用数学的基本原理和公式推导解决问题,数学这一专题常常和其他专题融合在一起。只不过在解题时需要数学的一些知识(比如加减乘除,常见的数学公式,推导等等)
常见题型
- 纯数字
- 加减乘除
比如和字符串结合,求解两个仅包含数字的字符串的和,或者与链表结合,求和两个链表。- 数字翻转
将一个有符号数字进行翻转,如123—>321- 进制转换
将二进制、十进制、罗马数字等相互转换
- 数学公式
- 给出波兰式或者逆波兰式字符,求解结果
- 根据数学性质求质数、丑数等
通用解法
对于纯数字的问题,那就是采用数学思想,注意一些进位和借位。还有就是计算机数值表达溢出的问题。
对于数学公式问题,那就是把握好原理,再结合一些常用的数据结构。
力扣原题
- P2 两数相加
/**
* 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) {
//数学求和:从个位开始,如果同一位加和大于10,进位1(add=1)
ListNode p1=l1,p2=l2;
ListNode res =null; 保存返回结果的链表,它要落后于p1
int step = 0; //表示进位
while(p1!=null && p2 !=null){
if(p1.val + p2.val + step>=10){
p1.val = p1.val + p2.val +step - 10;
step = 1;
}else{
p1.val = p1.val + p2.val + step;
step = 0;
}
//进入下一个
res = p1;
p1 = p1.next;
p2 = p2.next;
}
//如果l1更长
while(p1!=null){
if(step + p1.val >= 10){
p1.val = p1.val + step -10;
step = 1;
}else{
p1.val = p1.val + step;
step = 0;
break;
}
res = p1;
p1 = p1.next;
}
if(p2!=null)
res.next = p2;
while(p2!=null){
if(step + p2.val >= 10){
p2.val = p2.val + step -10;
step = 1;
}else{
p2.val = p2.val + step;
step = 0;
break;
}
res = p2;
p2 = p2.next;
}
if(step == 1){
ListNode newNode = new ListNode(1);
res.next =newNode;
}
return l1;
}
}
- p66 加1
class Solution {
public int[] plusOne(int[] digits) {
//首先判断会不会进位:如果digits[0]==9,说明有可能进位,最高位变成一,需要将数组整体往后移
//如果digits[0]!=9,那就从后往前加就行,因为不会造成最高位进位。
int length = digits.length;
int add = 1;
for(int i= length-1;i>=0;i--){
if(add + digits[i] == 10){
add = 1;
digits[i] = 0;
}
else{
digits[i] = digits[i] + add;
add = 0;
break;
}
}
if(add==1){
int[] newdigit = new int[length+1];
for(int i = length;i>0;i--){
newdigit[i]= digits[i-1];
}
newdigit[0] = 1;
return newdigit;
}else
return digits;
}
}