Problem 17. Letter Combinations of a Phone Number
Given a digit string, return all possible letter combinations that the number could represent.
A mapping of digit to letters (just like on the telephone buttons) is given below.
Input:Digit string "23" Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
Note:
Although the above answer is in lexicographical order, your answer could be in any order you want.
1.用一个ArrayList<String>记录结果,从头开始读取输入的数字,每读一个数字,在之前的结果上(List中的每一个元素)加上该数字对应的可能的字母
1.当List为空的时候,直接加入该数字的所有字母
代码如下:
public class Solution {
public List<String> letterCombinations(String digits) {
ArrayList<String> resList = new ArrayList<>();
for(int i =0;i < digits.length();i++){
resList = combine(resList,digits.charAt(i));
}
return resList;
}
public ArrayList<String> combine(ArrayList<String> list,char num){
char[][] dig = {{' '},
{' '},
{'a','b','c'},
{'d','e','f'},
{'g','h','i'},
{'j','k','l'},
{'m','n','o'},
{'p','q','r','s'},
{'t','u','v'},
{'w','x','y','z'}};
if(list.isEmpty()){
for(int i =0;i < dig[num - '0'].length;i++){
list.add(String.valueOf(dig[num - '0'][i]));
}
return list;
}
else{
ArrayList<String> newList = new ArrayList<>();
for(String str:list){
for(int i =0;i < dig[num - '0'].length;i++){
newList.add(str+dig[num - '0'][i]);
}
}
list.clear();
return newList;
}
}
}
Given a linked list, remove the nth node from the end of list and return its head.
For example,
Given linked list: 1->2->3->4->5, and n = 2. After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Try to do this in one pass.
解题思路:
1. 要求只能遍历一边链表,所以从头开始遍历链表,用一个ArrayList来记录各个Node里的值
2.遍历完链表之后,所有的值都记录在了ArrayList中,所以只需要删除下标为list.size()-n的元素,然后再用剩下的元素重新创建一个链表即可
代码如下:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
List<Integer> numList = new ArrayList<>();
ListNode temp = head;
while(temp != null){
numList.add(temp.val);
temp = temp.next;
}
int count = numList.size();
numList.remove(count - n);
if(count - 1==0) return null;
ListNode newHead= new ListNode(numList.get(0));
ListNode h = newHead;
for(int i = 1;i < numList.size();i++){
ListNode t = new ListNode(numList.get(i));
h.next = t;
h = h.next;
}
return newHead;
}
}
这个方法虽然只遍历了一次链表,但是结果是返回了一个新的链表,原来的链表仍然存在并占据着内存,这种方法内存消耗可能会比较大,所以在solution中找到了一个更加好的解法分享给大家:
1. 用两个指针同时遍历链表,一个快指针,一个慢指针
2. 只要快指针比慢指针快n+1个节点,那么当快指针遍历完数组之后,慢指针正好指在从后往前数第n+1个节点的位置,再下一次遍历的时候,直接跳过下一个节点(即目标节点)即可删除目标
代码如下:
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode start = new ListNode(0);
ListNode slow = start, fast = start;
slow.next = head;
//Move fast in front so that the gap between slow and fast becomes n
for(int i=1; i<=n+1; i++) {
fast = fast.next;
}
//Move fast to the end, maintaining the gap
while(fast != null) {
slow = slow.next;
fast = fast.next;
}
//Skip the desired node
slow.next = slow.next.next;
return start.next;
}