1.(2019.6.3)题目:给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
- 算法思想
这道题比较简单,由于两个数是逆序存储的,所以只要从表头开始每一位对齐相加,同时要判断是否要进位。 设置一个进位标志,在当位相加是判断是否有来自上一位的进位,然后再根据是否需要给下一位进位来更新标志。
当两个数字不对齐时,将对齐的部分加完之后,再将多余部分加在尾部,此时也要判断进位。
/**
* Definition for singly-linked list.
*
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
}*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
boolean c=false;
int sum=0;
ListNode head=new ListNode(-1);
head.next=null;
ListNode tail=head;
while(l1!=null&&l2!=null){
sum=l1.val+l2.val;
if(c){
sum++;
}
if(sum/10!=0)
c=true;
else
c=false;
sum=sum%10;
ListNode t=new ListNode(sum);
t.next=null;
tail.next=t;
tail=t;
l1=l1.next;
l2=l2.next;
}
while(l1!=null){
sum=l1.val;
if(c){
sum++;
}
if(sum/10!=0)
c=true;
else
c=false;
sum=sum%10;
ListNode t=new ListNode(sum);
t.next=null;
tail.next=t;
tail=t;
l1=l1.next;
}
while(l2!=null){
sum=l2.val;
if(c){
sum++;
}
if(sum/10!=0)
c=true;
else
c=false;
sum=sum%10;
ListNode t=new ListNode(sum);
t.next=null;
tail.next=t;
tail=t;
l2=l2.next;
}
if(c){
ListNode t=new ListNode(1);
t.next=null;
tail.next=t;
tail=t;
}
return head.next;
}
}
运行结果
执行用时 : 8 ms, 在Add Two Numbers的Java提交中击败了98.80% 的用户
内存消耗 : 38.4 MB, 在Add Two Numbers的Java提交中击败了98.76% 的用户
拓展解法:栈
其实也就是将每一位加完之后判断进位,更新进位后如栈,最后边出栈边头插法建链表即可。其实差不多。
2.(2019.6.4)题目:给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
- 算法思想
(1)暴力解法:两层循环嵌套,外层循环以第i个字母开头的字串,内层循环检查该字串的前几个字母为不重复。检查重复性可以用哈希,来减少一层循环。
class Solution {
Map<Character,Integer> h=new HashMap();
public int lengthOfLongestSubstring(String s) {
int max=0;
int now=0;
int num=s.length();
for(int i=0;i<num;i++){
char c=s.charAt(i);
h.clear();
now=count(s.substring(i));
if(now>max)
max=now;
if(max>(num-i)){
return max;
}
}
return max;
}
public int count(String s){
int n=s.length();
int now=0;
for(int i=0;i<n;i++){
if(!h.containsKey(s.charAt(i))){
now++;
h.put(s.charAt(i),i);
}
else{
return now;
}
}
return now;
}
}
运行结果:
执行用时 : 336 ms, 击败了6.67% 的用户
内存消耗 : 236.2 MB, 击败了5.00% 的用户
(2)优化方法:队列法。同样使用哈希来检查字符是否在队列口中。若下一个字符不在队中,则入队;若下一个字符在队列中,则先看是否需要更新最大队列长度,再出队一个字符,再重复判断。
class Solution {
Map<Character,Integer> h=new HashMap();
public int lengthOfLongestSubstring(String s) {
int max=0;
int now=0;//窗口
int n=s.length();
int i=0,j=0;
while(i<n&&j<n){
if(!h.containsKey(s.charAt(j))){//下一个字符不在窗口中
h.put(s.charAt(j),j);
j++;
now++;
if(now>max){
max=now;
}
}
else{//下一个字符在窗口中
h.remove(s.charAt(i),i);
i++;
now--;
}
}
if(now>max){
max=now;
}
return max;
}
}
运行结果:
执行用时 : 45 ms, 击败了50.04% 的用户
内存消耗 : 41.4 MB, 击败了69.08% 的用户