General problem solving ideas list:
Using a list of memory blocks of discrete, linear through a storage structure in each memory pointer stored in the memory and configured, it is a form of a linear linked list of tables.
Chain problem is a study of the basic coding capacity problem, the characteristics of this type of problem solution is not complicated, the difficulty is to prove the correctness of the solution and how to code. That is, whether the study can write bug free
code, mathematical algorithms examine a few will prove a problem.
- Using drawing techniques, the release of part of the brain space. To consider the issue by drawing several examples of small-scale, if the problem requires more than three pointer can be resolved, then the time cost of drawing, it can be accepted.
- Through case under normal circumstances the draw, the main idea of the disintegration of thinking algorithm. 3-5 is generally the case where the nodes.
- At this time, it is important not to immediately coded, but cite a few specific instances, to verify whether the general idea robust in Special Scenes, usually list the number of nodes 0,1,2,3,4, and head node pointer list, if it works with the tail node.
- Be patient, do not go too fast and commit code, the list in question is the ability to exercise your code review, the idea is very simple, the difficulty lies at the heart resistant, sober analysis. Believe me, you can always find the problem first coding.
So what is the general idea of it?
This is a pattern, thinking algorithm list problem is so few, you can apply mathematics to prove after watching a few typical cases can grasp the real difficulty lies in coding, chain issues involving pointer operations, error-prone, write that bug free
is not the thing, so the most important thing is to practice more.
Classic problem list:
- Design a single list:
Here we rely on sentry ideas
class MyLinkedList:
def __init__(self):
"""
初始化一个链表,使用一个永不存数据的节点作为哨兵,
这样可以简化,在插入删除操作中对头节点与尾节点插入时的条件判读,
进而提高速度。
"""
self.sb = ListNode(-1)
self.le = 0
def get(self, index):
"""
通过索引获取链表中的节点。
"""
head = self.sb.next
if index < 0 or index >= self.le or head == None:
return -1
for i in range(index):
head = head.next
return head.val
def addAtHead(self, val):
"""
在头节点的位置插入节点,哨兵思想使其不用判读非空情况。
"""
head = self.sb.next
self.sb.next = ListNode(val)
self.sb.next.next = head
self.le += 1
def addAtTail(self, val):
"""
在尾部插入节点
"""
tmp = self.sb
for i in range(self.le):
tmp = tmp.next
tmp.next = ListNode(val)
self.le += 1
def addAtIndex(self, index, val):
"""
在指定索引的位置插入节点
"""
if index < 0 or index > self.le :
return -1
pre = self.sb
for i in range(index):
pre = pre.next
tmp = pre.next
pre.next = ListNode(val)
pre.next.next = tmp
self.le += 1
def deleteAtIndex(self, index):
"""
指定index的位置删除节点
"""
if index < 0 or index >= self.le:
return
pre = self.sb
for i in range(index) :
pre = pre.next
pre.next = pre.next.next
self.le -= 1
- Determining whether a cycloalkyl list
Classic double pointer thinking three questions: Is there a list interpretation of the intersection ring, chain and ring, find the length of the loop.
Define two pointers, from the beginning, a two-step each pass,
a step, there are two intersecting rings,
disjoint take two steps first to the tail pointer, then the interpretation acyclic.
class Solution(object):
def hasCycle(self, head):
if head is None or head.next is None:
return False
fast ,slow = head,head
while fast is not None and fast.next is not None:
fast = fast.next.next
slow = slow.next
if slow == fast:
return True
return False
- Analyzing the entry point of the ring
After the meet cursor speed, the fast re-pointing to the head node pointer,
two pointers starts walking while each walking step. When meet again,
that is the entry point of the ring.
class Solution(object):
def detectCycle(self, head):
if head == None or head.next == None:
return None
fast = head.next.next
slow = head.next
while fast != None and fast.next != None:
fast = fast.next.next
slow = slow.next
if fast == slow:
break
if fast == None or fast.next == None:
return None
fast = head
while fast != slow:
fast = fast.next
slow = slow.next
return fast
- Solving loop length
determined meeting point, continue to move a pointer, each step, recording the number of walking,
the other pointer does not move in situ, to meet the length is the number again.
Very simple, the brain make it.
pass
So the question is, the front two algorithms correct it, how to use mathematics to prove it?
Chain has proven algorithm ring :
proof:
1. There is provided a pointer when walked slowly ring entry point position, the distance Ll representatives head to the entry point, the pointer is slow walking distance, which is certainly quick pointer to the ring, from the entrance set point L2 of.
2. I representative of the number of steps to catch up with slow pointer pointer to go faster.
Total number of steps slow the code pointer 3. S1, S2 of the code pointer fast total number of steps.
4. C represents a cycloalkyl perimeter.
If the fast and slow pointer Pointer met, then it must meet (S1+i-L1)mod C = (S2+2i-L1)mod C
, is subtracted by subtracting the number of steps L1 to the ring before, the i-step slow pointer chasing pointer actually go so fast step 2i. Therefore, to meet certain will meet this condition.
Excluded influence the number of steps before the ring, only to see the ring with respect to the entry point from the position after the ring, are: S1 = L1
, S2 - L1 = NC + L2
, where N is the number of rings has been much surround ring. Into the above equation i mod C = (NC+L2+2i) mod C
is further order was: (L2 + i) mod C = 0
When, N 0 at understood, L2 < C
, I must be an integer in the range of solution, it must meet the speed of the pointer.
Entry point algorithm ring Proof:
According to equation (4) => (4) => (mn-1) L2 + L2 = s => (mn-1) L2 + P1 + P2 = L1 + P1 <=> (mn -1) + P2 = L2 of Ll
(the first intersection point Pl is defined to meet the length of chasing points, P2 is the length of the meeting point to the first point of intersection, i.e., P1 + P2 = L2)
this equation indicates that the list It does not include the length of the loop equal to the length of the meeting point to the first point of intersection of the ring plus the length of an integer multiple.
- Seeking two intersection points list
two pointers, pointing to two head of the list, when constantly move forward,
as to who the tail, then head back to another list. Intersecting the list,
first to the tail of the list must be short, long head back to the list,
when the pointer is also a long list of departure to the end,
it has gone through is just one more step to the difference between the number of nodes in the length of the list,
at this time, the long chain pointer back to the head of the short chain,
both aligned position, to move forward in this final encounter, namely the intersection point.
class Solution(object):
def getIntersectionNode(self, headA, headB):
p1 ,p2 = headA,headB
while p1 != p2:
p1 = headB if p1 == None else p1.next
p2 = headA if p2 == None else p2.next
return p1
- The reciprocal of the n-th node deletes single chain of
two pointers, a go ahead n steps, and then again go with two hands,
if the tail pointer reaches the go, then go after the node pointer for deletion precursor node.
Penultimate n, in fact, the first positive number Ln + 1, L is the length of the list,
so Ln is just to delete the precursor node.
Go ahead n steps, after the walk is Ln, and
this is precisely what the second pointer in a node of Ln.
class Solution(object):
def removeNthFromEnd(self, head, n):
pre ,last = head,head
for i in range(n):
pre = pre.next
if pre == None:
return head.next
while pre.next != None:
pre = pre.next
last = last.next
last.next = last.next.next
return head
Pointer operations
this problem is to examine pointer checking boundary condition of operation, some of the coding capability requirements.
- Single chain reversing
two pointers implemented Version c:
class Solution(object):
def reverseList(self, head):
"""
使用三个指针,完成单链表操作。
"""
if head == None:
return None
pre = None
next = head.next
while head != None:
head.next = pre
pre = head
head = next
if next != None:
next = next.next
return pre
- All the elements to val remove the list of
considerations boundary conditions, exceptions, the first cycle is the key
to traverse the precursor delete Val methods investigated by the linked list of nodes 0,1,2,3 get,
unable to adapt to the head node as well as the head node is a continuous need to remove the Val.
class Solution(object):
def removeElements(self, head, val):
if head == None:
return None
while head != None and head.val == val:
if head.next == None:
return None
else:
head = head.next
pre = head
while pre.next != None:
if pre.next.val == val:
pre.next = pre.next.next
else:
pre = pre.next
return head
- Parity list
next to each other by means of two pointers, staggered forward, to achieve independent traversing smart parity node, then own series, and combined.
The difficulty lies in the relationship between the pointer no mistake, you can use drawing techniques assist thinking, problem lists test programming capability, to be tolerant, patient and check this is the key.
class Solution(object):
def oddEvenList(self, head):
if head is None:
return head
odd = head
even = head.next
if even is None:
return head
odd_prev = odd
even_prev = even
even_head = even
while even is not None and even.next is not None:
odd = even.next
even = odd.next
odd_prev.next = odd
even_prev.next = even
odd_prev = odd
even_prev = even
odd.next = even_head
return head
- Palindromic chain
speed pointer to find the midpoint, the second half of the list reverse, neutral position and over again traverse the list, which comparison value is determined by one palindromic.
The focus here is in the appropriate abstract encoding process can be simplified code logic, greatly enhance the accuracy and readability of the coding.
class Solution(object):
def isPalindrome(self, head):
if head is None or head.next is None:
return True
mid = self.getMid(head)
mid.next = self.getFanZhuan(mid.next)
p,q = head,mid.next
while q is not None and p.val == q.val:
q = q.next
p = p.next
self.getFanZhuan(mid.next)
return q == None
def getMid(self,head):
fast,slow = head.next,head
while fast is not None and fast.next is not None:
fast = fast.next.next
slow = slow.next
return slow
def getFanZhuan(self,head):
if head is None or head.next is None:
return head
pre,curr,next = None,head,head.next
while curr is not None:
curr.next = pre
pre = curr
curr = next
next = None if next is None else next.next
return pre
- Design doubly linked list
doubly linked list of more complex design than the single list of some, but understand if the use of sentinel in the list of words, it is still very easy, but this question I actually did three days, well I seven every morning half will do a question. should spend a total of 40 minutes, or I was too dishes, and there is such a problem when the design data structure, to write multiple methods, when we review the code, but also consider the multiple functions with each other the impact of call,
which is the class level "invariant", requires in-depth thinking the role of each action, careful understanding of pre- and post-conditions for each behavior, as well as the entire object lifecycle must maintain a What kind of constant state Yes.
class MyLinkedList(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.head = ListNode(-1)
self.tail = ListNode(-1)
self.head.next = self.tail
self.tail.prev = self.head
self.length = 0
def get(self, index):
"""
Get the value of the index-th node in the linked list. If the index is invalid, return -1.
:type index: int
:rtype: int
"""
if index < 0 or index >= self.length:
return -1
return self.getNode(index).val
def getNode(self,index):
frist = self.head.next
for i in range(index):
frist = frist.next
return frist
def addAtHead(self, val):
"""
Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list.
:type val: int
:rtype: void
"""
frist = self.head.next
node = ListNode(val)
self.head.next = node
node.prev = self.head
node.next = frist
frist.prev = node
self.length += 1
def addAtTail(self, val):
"""
Append a node of value val to the last element of the linked list.
:type val: int
:rtype: void
"""
last = self.tail.prev
node = ListNode(val)
self.tail.prev = node
node.next = self.tail
last.next = node
node.prev = last
self.length += 1
def addAtIndex(self, index, val):
"""
Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted.
:type index: int
:type val: int
:rtype: void
"""
if index < 0 or index > self.length:
return
if index == self.length:
self.addAtTail(val)
return
old = self.getNode(index)
node = ListNode(val)
pre = old.prev
pre.next = node
node.prev = pre
node.next = old
old.prev = node
self.length += 1
def deleteAtIndex(self, index):
"""
Delete the index-th node in the linked list, if the index is valid.
:type index: int
:rtype: void
"""
if index < 0 or index >= self.length:
return
node = self.getNode(index)
pre = node.prev
next = node.next
pre.next = next
next.prev = pre
node.next = None
node.prev = None
self.length -= 1
- Splicing two ordered lists
this question is the key to handling of exceptions, the list may have entered two are empty, it may vary in length. Both need to be addressed separately
class Solution(object):
def mergeTwoLists(self, l1, l2):
if l1 is None and l2 is None:
return None
elif l1 is None:
return l2
elif l2 is None:
return l1
sb ,headA,headB = ListNode(-1),l1,l2
headSB = sb
while headA and headB :
if headA.val > headB.val:
sb.next = headB
headB = headB.next
elif headA.val < headB.val:
sb.next = headA
headA = headA.next
else:
sb.next = headA
headA = headA.next
sb = sb.next
sb.next = headB
headB = headB.next
sb = sb.next
if headA:
sb.next = headA
elif headB:
sb.next = headB
return headSB.next
- The two figures represent the sum of the list in reverse order
this problem using Sentinel simplifies the code, while paying attention to the handling of the carry,
is very well done.
class Solution(object):
def addTwoNumbers(self, l1, l2):
rem = 0
dummy = ListNode(0)
p = dummy
while l1 or l2 or rem:
s = (l1.val if l1 else 0) + (l2.val if l2 else 0) + rem
rem = s/10
p.next = ListNode(s%10)
p = p.next
if l1:
l1 = l1.next
if l2:
l2 = l2.next
return dummy.next
- Flat multistage doubly linked list
detailed explanation see here
this emphasis on the problem, the handling of a pointer, you can draw assisted think,
traverse the list subject, no child will continue to traverse the list.
The entire procedure is completed in one cycle.
There is a linked list traversal sub-chained give the sub-list head pointer and the tail of the next sub-tail node list points to the next pointer of the current main chain, next if not empty, it is prev pointer to the tail of the linked list node, and then update the list of sub-head node again, so that the current head node pointer next master list traversal node to the sub-list, and the sub-list head node prev pointer in turn point to it, and point it to the sub pointer assigned to child none, the next current pointer directly to the combined tail pointer of the linked list, thereby reducing the number of its traverse. Reciprocating iteration, according to the specific code to be understood that the drawing.
This problem more complicated pointer, drawing the assignment analysis is to writebug free
critical.
class Solution(object):
if not head:
return None
p = head
while p:
if not p.child:
p = p.next
continue
p1 = p.child
p2 = p.child
while p2.next:
p2 = p2.next
p2.next = p.next
if p.next:
p.next.prev = p2
p.next = p1
p1.prev = p
p.child = None
p = p1
return head
- Copy pointer with random list of
this question is the key to the understanding of random pointer, copy node when replication of random pointer is relative, must ensure that a random node pointer relatively unchanged.
Details click here
class Solution(object):
def copyRandomList(self, head):
if not head:
return None
p = head
while p:
tmp = RandomListNode(p.label)
tmp.next = p.next
p.next = tmp
p = tmp.next
p = head
while p:
if p.random:
p.next.random = p.random.next
p = p.next.next
n,o = head.next,head
new = n
while n:
o.next = n.next
o = o.next
if not o:
break
n.next = o.next
n = n.next
return new
- Rotating the list
the best solution to this problem can be done in a constant space, linear time
to reverse the whole, find the split point, two of the portions are in reverse order.
Note that, when the reverse order to specify a tail pointer, because a continuous chain
class Solution(object):
def rotateRight(self, head, k):
if head is None:
return None
if k == 0:
return head
count = 0
end = None
tmp = head
while tmp:
tmp = tmp.next
count += 1
head = self.nx(head,end)
k = k % count
tmp = head
while k != 0:
tmp = tmp.next
k -= 1
end = tmp
new_head = self.nx(head,end)
head.next = self.nx(end,None)
return new_head
def nx(self,head,end):
if head is None:
return None
pre,curr,next = None,head,head.next
while curr != end:
curr.next = pre
pre = curr
curr = next
next = next.next if next else None
return pre
- Ordered list convert binary search tree
details
this question is essentially linear relationship between the structure and the tree structure of study,
how to store a binary search tree with linear structure? Linear table can be ordered, linear table can be an array, a linked list may be. If this is so, how to use the table in turn ordered linear structure binary search tree? Dichotomy is the key, the dichotomy is a linear mapping relation table and ordered binary search, then how to take dichotomy midpoint?
An array index can be calculated index, the list can use a pointer speed, ok problem has been solved at this time, look at the code.
class Solution(object):
def sortedListToBST(self, head):
return self.insterC(head,None)
def insterC(self,head,tail):
if head is tail:
return None
if head.next is tail:
return TreeNode(head.val)
fast = mid = head
while fast is not tail and fast.next is not tail:
mid = mid.next
fast = fast.next.next
tree = TreeNode(mid.val)
tree.left = self.insterC(head,mid)
tree.right = self.insterC(mid.next,tail)
return tree
- Twenty-two exchange the list of nodes
for this problem is similar to the list in reverse order of ideas, but as long as the correct understanding of the relationship between the linked list pointers, attention predecessor, the current node, the three subsequent transformation. Note that the code inspection, inspection of boundary conditions, analyze exceptions can writebug free
, with emphasis on patience, there must be tolerant.
Detail
class Solution(object):
def swapPairs(self, head):
if head is None:
return head
sb = ListNode(-1)
sb.next = head
a = sb
b = head
c = head.next
while c:
a.next = c
b.next = c.next
c.next = b
a = b
b = b.next
if b is None:
break
c = b.next
return sb.next
- Sort list
on this question is essentially the list of merge sort of realization, subject of the request O (nlong), linked list to achieve the advantages is that you can complete the merge sort merge under constant space, the disadvantage is the midpoint of the query can not think of an array as complete in constant time , so its performance is slower than an array of some, but also in the same order of magnitude, and does not require continuous storage space, as well as extra space, in some cases also a good choice.
Detail
class Solution(object):
def sortList(self, head):
if head is None or head.next is None :
return head
mid = self.getMid(head)
left = self.sortList(head)
right = self.sortList(mid)
return self.merge(left,right)
def getMid(self,head):
m,k = head,head
sb = ListNode(-1)
sb.next = head
while k and k.next:
k = k.next.next
m = m.next
sb = sb.next
sb.next = None
return m
def merge(self,a,b):
sb = ListNode(-1)
curr = sb
while a and b:
if a.val >= b.val:
curr.next = b
b = b.next
else:
curr.next = a
a = a.next
curr = curr.next
if a:
curr.next = a
elif b:
curr.next = b
return sb.next
- Rearrangements list
details
this question is the key to understanding the problem correctly, write a few test cases found that the taste is a combination of three common behaviors linked list, access to the midpoint of the list, the list in reverse order, cross-merge list.
class Solution(object):
def reorderList(self, head):
if not head or not head.next:
return
if not head.next.next:
return
mid = self.get_mid(head)
head1 = self.nx(mid)
head = self.marge(head,head1)
def get_mid(self,head):
pre = ListNode(-1)
pre.next = head
fast,slow = head,head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
pre = pre.next
pre.next = None
return slow
def nx(self,head):
pre, cur, next = None,head,head.next
while cur:
cur.next = pre
pre = cur
cur = next
if next:
next = next.next
return pre
def marge(self,head1,head2):
dummy = ListNode(-1)
d = dummy
p, q = head1,head2
while p and q:
d.next = p
p = p.next
d = d.next
d.next = q
q = q.next
d = d.next
if q:
d.next = q
elif p:
d.next = p
return dummy.next
- List the components
key to understanding the concept of problem-solving questions in the definition of the components, using the map key characteristics and to determine the counting strategy to solve problems, the key is this question correctly understand the new concepts and identify the algorithm in the classic mode - a collection of search.
class Solution:
def numComponents(self, head, G):
if head is None or len(G) == 0:
return 0
count = 0
cur = head
GMap = {}
for v in G:
GMap[v] = 0
while cur:
if cur.val in GMap and (cur.next is None or cur.next.val not in GMap):
count += 1
cur = cur.next
return count
- Partition list 01
divided into two steps solved to find the first division rule.
The second rule cutting press.
The rules are simple meaning of the questions is to first split the remainder shared equally then
this problem is to find the law, its mathematical expression and a good package operating behavior.
class Solution:
def splitListToParts(self, root, k):
p = root
size = 1
while p and p.next:
size += 1
p = p.next
mod = size % k
num = int(size / k)
res = []
tmp = root
while k != 0:
if mod != 0:
root = self.splitListNodeByLen(tmp,num+1)
mod -= 1
else:
root = self.splitListNodeByLen(tmp,num)
res.append(tmp)
tmp = root
k -= 1
return res
def splitListNodeByLen(self,root,l):
if not root or l <= 0:
return root
pre = None
while l > 0:
pre = root
root = root.next
l -= 1
pre.next = None
return root
- Two numbers together II
to this problem is even adding an upgraded version of the table, the table is no longer even need to reverse the discretion of disintegration pattern that is the first general to specific approach, this question my solution is relatively poor, do not learn from best practices , I just wanted to come out, since there was no starting from the low, but also operational problems, think of using a stack of such direct aids to deal with.
But the additional complexity introduced during and after thinking about how to optimize.
class Solution:
def addTwoNumbers(self, l1, l2):
s1, s2 = [], []
tmp1 ,tmp2 = l1, l2
while tmp1:
s1.append(tmp1.val)
tmp1 = tmp1.next
while tmp2:
s2.append(tmp2.val)
tmp2 = tmp2.next
c = 0
node = ListNode(-1)
root = node
while len(s1) != 0 and len(s2) != 0:
num = s1[-1] + s2[-1] + c
s1 = s1[:len(s1)-1]
s2 = s2[:len(s2)-1]
if num >= 10:
node.val = num - 10
c = 1
else:
node.val = num
c = 0
if len(s1) == 0 and len(s2) == 0:
if c == 1:
node.next = ListNode(-1)
node = node.next
node.val = c
break
node.next = ListNode(-1)
node = node.next
while len(s1) != 0:
num = s1[-1] + c
if num >= 10:
node.val = num - 10
c = 1
else:
node.val = num
c = 0
s1 = s1[:len(s1)-1]
if len(s1) == 0:
if c == 1:
node.next = ListNode(-1)
node = node.next
node.val = c
break
node.next = ListNode(-1)
node = node.next
while len(s2) != 0:
num = s2[-1] + c
if num >= 10:
node.val = num - 10
c = 1
else:
node.val = num
c = 0
s2 = s2[:len(s2)-1]
if len(s2) == 0:
if c == 1:
node.next = ListNode(-1)
node = node.next
node.val = c
break
node.next = ListNode(-1)
node = node.next
return self.nx(root)
def nx(self,root):
if root is None:
return None
pre = None
next = root.next
while root:
root.next = pre
pre = root
root = next
if next:
next = next.next
return pre
- Delimited list 02
this problem is fast row in the partition table even realize.
class Solution:
def partition(self, head, x):
h1,h2 = ListNode(-1),ListNode(-1)
dummy = ListNode(-1)
dummy.next = head
pre = dummy
tmp1,tmp2 = h1,h2
while pre and pre.next:
tmp = pre.next
pre.next = None
pre = tmp
if tmp.val >= x:
tmp1.next = tmp
tmp1 = tmp1.next
else:
tmp2.next = tmp
tmp2 = tmp2.next
tmp2.next = h1.next
return h2.next
- List II reverse
this problem pointer drawing more aid more efficient.
class Solution:
def reverseBetween(self, head, m, n):
count = 0
dummy = ListNode(-1)
pre = dummy
pre.next = head
while count < m-1:
pre = pre.next
count += 1
last = pre
while count < n:
last = last.next
count += 1
cur = pre.next
next = last.next
self.reverse(cur, last)
pre.next = last
head = dummy.next
cur.next = next
return head
def reverse(self, cur,last):
last.next = None;
pre = None
next = cur.next
while cur:
cur.next = pre
pre = cur
cur = next
if next:
next = next.next
- Two numbers together
using Sentinel mode
class Solution(object):
def addTwoNumbers(self, l1, l2):
"""
"""
rem = 0
dummy = ListNode(0)
p = dummy
while l1 or l2 or rem:
s = (l1.val if l1 else 0) + (l2.val if l2 else 0) + rem
rem = s/10
p.next = ListNode(s%10)
p = p.next
if l1:
l1 = l1.next
if l2:
l2 = l2.next
return dummy.next
- Plus One Linked List (even Table 1 plus operation)
leetCode payment questions, very simple but very clever. I did not think the original
idea is to traverse the list to find the first one from the right is not the number 9, if no such number, a description of all numbers are 9, then create a new node value of 0 in the header, processing for adding 1, then all the numbers to the right are set to 0. for example:
Such as 1-> 2-> 3, then the first number is not a 9 to 3, adding 1 to 3, 4 becomes the right node does not, so no processing, returns 1-> 2-> 4.
Another example 8-> 9-> 9, first find the number 9 is not 8, the processing for adding 1 becomes 9, and the latter figure are set to 0, the result obtained 9-> 0-> 0 .
Let's look at the case of 9-> 9-> 9, can not find the number 9 is not, then again in front of a new node is 0, the processing for adding 1 becomes 1, the latter figure are set to 0, to give 1-> 0-> 0-> 0.
class Solution {
public:
ListNode* plusOne(ListNode* head) {
ListNode *cur = head, *right = NULL;
while (cur) {
if (cur->val != 9) right = cur;
cur = cur->next;
}
if (!right) {
right = new ListNode(0);
right->next = head;
head = right;
}
++right->val;
cur = right->next;
while (cur) {
cur->val = 0;
cur = cur->next;
}
return head;
}
};
Design Phone Directory (phone design dictionary)
here , he said very clearly, I do not say that again, mainly on the design of the data structure, in fact, want this issue to whether the most common structure to meet the requirements based on experience, try a combination of inadequate data structures, the key is to define what information you need to know to make you one step closer to the correct answer, it takes practice and summary.Convert Binary Search Tree to Sorted Doubly Linked
List to a binary search tree, converted into a double loop table.
Very classic a question, LeetCode charges, OJ no way to do, just go the local environment. So go with wrote a solution.
This problem using the idea of divide and conquer, recursive implementation. Mode can be regarded as the original problem: the left sub-tree root and ring combined to form a ring, and then combined to form a ring with a right subtree. Thus,
the sub-question is: 1. "left subtree root right subtree" ring, 2 merge.
Recursive base apparently the root node is empty, return directly.
Recursive part is: left and right ring
every thing is done recursively: a root ring, with left and right root three rings, two merging operation is to merge into a circular list of function attached table.
type TreeNode struct {
Left *TreeNode
Right *TreeNode
Val int
}
func BST2DLL(root *TreeNode) *TreeNode {
if root == nil{
return nil
}
aLast := BST2DLL(root.Left)
bLast := BST2DLL(root.Right)
root.Left = root
root.Right = root
aLast = Append(aLast,root)
aLast = Append(aLast,bLast)
return aLast
}
func Append(a,b *TreeNode) *TreeNode {
if a == nil{
return b
}
if b == nil{
return a
}
aLast := a.Left
bLast := b.Left
Join(aLast, b)
Join(bLast, a)
return a
}
func Join(a, b *TreeNode) {
a.Right = b
b.Left = a
}
30. A the Insert INTO A Cyclic circulating the Sorted List ordered linked list insert node point
of this question, the analysis is to examine a variety of conditions, if during the first empty list, is inserted between the maximum and minimum values, less than the minimum or greater than the maximum. The different situations can think clearly. According to the number of axes.
Here in great detail
31. k th group inverted list
by using pointers sentinel reduction operation, using k as a counter control pre, left, right boundary pointer operation. The pointer moves counter to the correct position, inverted list. Clumsy but effective method is relatively simple Haha, after a time optimization, I am still as much rinse title, experience more of the type of data to collect more basic training model.
class Solution:
def reverseKGroup(self, head, k):
"""
:type head: ListNode
:type k: int
:rtype: ListNode
"""
if k <= 0 or not head or not head.next:
return head
dummy = ListNode(-1)
dummy.next = head
cur = head
pre = dummy
while cur:
left,right = cur,cur
for i in range(k-1):
cur = cur.next
if cur is None:
return dummy.next
right = cur
self.nx(pre,left,right)
cur = left
pre = left
cur = cur.next
return dummy.next
def nx(self,pre,l,r):
if not pre or not l or not r or l == r:
return l
p ,cur,next = pre,l,l.next
tmp = r.next
while cur != tmp:
cur.next = p
p = cur
cur = next
if next:
next = next.next
pre.next = p
l.next = tmp
32. Merge K sort the list
this question can be very subtle, but I am here to give an intuitive solution of violence, have the opportunity to continue to optimize. This problem can be understood as the largest selection of each node from the list, from which they removed to form a new use of sentinel node, then the list will be updated continuously down generations, finally ending when the list is empty.
class Solution:
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
dummy = ListNode(-1)
cur = dummy
while len(lists) != 0:
index = self.min(lists)
if not lists[index]:
del lists[index]
continue
cur.next = lists[index]
if lists[index] and lists[index].next:
lists[index] = lists[index].next
else:
del lists[index]
cur = cur.next
return dummy.next
def min(self,lists):
m = lists[0]
index = 0
i = 1
while i<len(lists):
if lists[i] and m and m.val > lists[i].val:
m = lists[i]
index = i
i += 1
return index
33. The node of the list to delete
and rather clever, you have only given node, there is no pointer predecessor node. Clever use of the assignment of thinking to solve.
class Solution:
def deleteNode(self, node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
tmp = node.next
node.next = node.next.next
tmp.next = None
node.val = tmp.val
34. The list of intermediate nodes
would have been in the order of this problem on the front, later I discovered that actually did not write, add it here. Many times before mentioned, the intermediate node, the pointer speed die
class Solution(object):
def middleNode(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head and not head.next:
return head
slow,fast = head,head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
return slow