这篇是平时闲暇时间在LeetCode上做题的整理记录,记录的都是我第一次成功提交时的解法,可能时间复杂度不是最佳,但是达到了LeetCode上的时间空间复杂度要求,要查看时间/空间复杂度最佳的解法,可以参照这里
2. 两数相加
给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode mark = new ListNode(0);
ListNode l3 = mark;
int push = 0;
int result;
while(l1!=null && l2!=null) {
if(l1.val + l2.val + push >= 10) {
result = l1.val + l2.val + push - 10;
push = 1;
}
else {
result = l1.val + l2.val + push;
push = 0;
}
mark.next = new ListNode(result);
mark = mark.next;
l1=l1.next;
l2=l2.next;
}
while(l1!=null) {
if(l1.val + push >= 10) {
result = l1.val + push - 10;
push = 1;
}
else {
result = l1.val + push;
push = 0;
}
mark.next = new ListNode(result);
mark = mark.next;
l1 = l1.next;
}
while(l2!=null) {
if(l2.val + push >= 10) {
result = l2.val + push - 10;
push = 1;
}
else {
result = l2.val + push;
push = 0;
}
mark.next = new ListNode(result);
mark = mark.next;
l2 = l2.next;
}
if(push!=0)
mark.next = new ListNode(1);
return l3.next;
}
6. Z字形变换
将字符串 "PAYPALISHIRING"
以Z字形排列成给定的行数:
示例 :
输入: s = "PAYPALISHIRING", numRows = 4
输出: "PINALSIGYAHRPI"
解释:P I N A L S I G Y A H R P I
public String convert(String s, int numRows) {
if (numRows == 1) return s;
StringBuilder sb = new StringBuilder();
int n = s.length();
int len = 2 * (numRows - 1);
for (int j = 0; j < numRows; j++) {
int i = j;
while (i < n) {
sb.append(s.charAt(i));
if (j != 0 && j != numRows - 1 && (i + len - 2 * j) < n) {
sb.append(s.charAt(i + (numRows - 1 - j) * 2));
}
i += (numRows - 1) * 2;
}
}
return sb.toString();
}
9.回文数
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例 1:
输入: 121
输出: true
示例 2:
输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
public boolean isPalindrome(int x) {
Integer n = x;
String str = n.toString();
int i,j;
i=0;
j=str.length()-1;
while(i<=j) {
if(str.charAt(i)==str.charAt(j)) {
i++;
j--;
}
else
return false;
}
return true;
}
10. 正则表达式匹配
给定一个字符串 (s
) 和一个字符模式 (p
)。实现支持 '.'
和 '*'
的正则表达式匹配。
'.' 匹配任意单个字符。
'*' 匹配零个或多个前面的元素。
匹配应该覆盖整个字符串 (s
) ,而不是部分字符串。
说明:
s
可能为空,且只包含从a-z
的小写字母。p
可能为空,且只包含从a-z
的小写字母,以及字符.
和*
。
示例 1:
输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。
示例 2:
输入:
s = "aa"
p = "a*"
输出: true
解释: '*' 代表可匹配零个或多个前面的元素, 即可以匹配 'a' 。因此, 重复 'a' 一次, 字符串可变为 "aa"。
示例 3:
输入:
s = "ab"
p = ".*"
输出: true
解释: ".*" 表示可匹配零个或多个('*')任意字符('.')。
示例 4:
输入:
s = "aab"
p = "c*a*b"
输出: true
解释: 'c' 可以不被重复, 'a' 可以被重复一次。因此可以匹配字符串 "aab"。
public static boolean isMatch(String s, String p) {
return myMatch(s,s.length()-1,p,p.length()-1);
}
public static boolean myMatch(String s, int i, String p, int j) {
if(j==-1)
if(i==-1)
return true;
else
return false;
if(i==-1 && p.charAt(j)!='*')
return false;
if(p.charAt(j)=='*') {
if(i>-1 && (p.charAt(j-1) == '.' || p.charAt(j-1)==s.charAt(i)))
if(myMatch(s, i-1, p, j))
return true;
return myMatch(s, i, p, j-2);
}
if(p.charAt(j) == '.' || p.charAt(j) == s.charAt(i))
return myMatch(s, i-1, p, j-1);
return false;
}
12.整数转罗马数字
罗马数字包含以下七种字符: I
, V
, X
, L
,C
,D
和 M,分别表示1、5、10、50、100、500、1000
例如, 罗马数字 2 写做 II
,即为两个并列的 1。12 写做 XII
,即为 X
+ II
。 27 写做 XXVII
, 即为 XX
+ V
+ II
。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII
,而是 IV
。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX
。这个特殊的规则只适用于以下六种情况:
I
可以放在V
(5) 和X
(10) 的左边,来表示 4 和 9。X
可以放在L
(50) 和C
(100) 的左边,来表示 40 和 90。C
可以放在D
(500) 和M
(1000) 的左边,来表示 400 和 900。
给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。
示例 1:
输入: 58
输出: "LVIII"
解释: C = 100, L = 50, XXX = 30, III = 3.
示例 2:
输入: 1994
输出: "MCMXCIV"
解释: M = 1000, CM = 900, XC = 90, IV = 4.
public String intToRoman(int num) {
StringBuilder sb = new StringBuilder();
int[] unit = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000};
String[] flag = {"I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M"};
int n;
for (int i = 12; i >= 0; i--) {
n = num / unit[i];
num = num % unit[i];
for (int j = 0; j < n; j++) {
sb.append(flag[i]);
}
}
return sb.toString();
}