右移K位的过程就是按后K位和剩余位分成两部分,分别逆序排列,然后把整个数组逆序排列。
变换过程通过以下步骤完成:
1.逆序排列 abcd: abcd1234 -> dcba1234;
2.逆序排列 1234: dcba1234-> dcba4321;
3.全部逆序 dcba4321->1234abcd。
https://blog.csdn.net/sicofield/article/details/8850269#
方法1:将单链表储存为数组,然后按照数组的索引逆序进行反转。
方法2:使用三个指针遍历单链表,逐个链接点进行反转。
Node * ReverseList(Node *head)
{
Node *p1,*p2,*p3;
if(head==NULL||*head==NULL)
return head;
p1=head;
p2=p1->next;
while(p2) //注意条件
{
p3=p2->next; //要改变p2->next的指针,所以必须先保留p2->next
p2->next=p1;
p1=p2; //循环往后
p2=p3;
}
head->next=NULL; //原先的head已经变成tail,别忘了置空,只有到这步才能置空
*head=p1;
return head;
}
方法3:从第2个节点到第N个节点,依次逐节点插入到第1个节点(head节点)之后,最后将第一个节点挪到新表的表尾。
方法1的问题是浪费空间。方法2和方法3效率相当。一般方法2较为常用。
Void ReversList(LIST p)
{
if(p->next)
ReversList(p-next);
visit(p->data);
}O(?)
1.快慢指针相遇
从头指针开始,每次分别移动2、1个节点
2.每个节点设flag
map Node;
3.穷举 线性查找到HashSet
每遍历到一个新节点,就用新节点和HashSet集合当中存储的节点作比较,如果发现HashSet当中存在相同节点ID,则说明链表有环,如果HashSet当中不存在相同的节点ID,就把这个新节点ID存入HashSet。
时间复杂度:HashSet查找为O(1),使得线性查找使得O(N*N)变为O(N*1)
空间复杂度:O(1)变为O(N)
快慢指针法 若无环,快指针先为空
fast = fast->next ? fast->next : NULL; //fast->next == NULL?
if (NULL == fast) break;
https://www.jianshu.com/p/ef71e04241e4
https://www.cnblogs.com/dirkhe/p/6790858.html
p1和p2分别都是head指针,先将p2向右移动k次。(此时k为2)
只需要继续保持p1和p2等间距的右移,当p2的next为null,则证明p1所指的结点的值为倒数第k个节点的值
快慢指针方法
建立两个指针,一个指针一次遍历两个节点,另一个节点一次遍历一个节点,当快指针遍历到空节点时,慢指针指向的位置为链表的中间位置。
https://blog.csdn.net/u010983881/article/details/78896293
1.穷举 HashSet两次遍历 时间复杂度为:O(max(len1+len2);空间复杂度O(len1)
2.设flag
3.利用有环链表思路
对于两个没有环的链表相交于一节点,则在这个节点之后的所有结点都是两个链表所共有的。如果它们相交,则最后一个结点一定是共有的,则只需要判断最后一个结点是否相同即可。时间复杂度为O(len1+len2)。
对于相交的第一个结点,则可求出两个链表的长度,然后用长的减去短的得到一个差值 K,然后让长的链表先遍历K个结点。
还可以这样:其中一个链表首尾相连,检测另外一个链表是否存在环,如果存在,则两个链表相交,而检测出来的依赖环入口即为相交的第一个
next函数:
(1)next[0]= -1,任何串的第一个字符的模式值规定为-1
(2)next[j] = -1,模式串t中下标为j的字符,如果与首字符相同,前k个字符不等或者相等但t[j] == t[k](匹配夹带了a[j])。1≤k
t=”aba” 则 next[2]=-1,因k取1,t[2]与首字母相同,但前1个不匹配
t=”abC abC ad” 则 next[6]=-1,因k取3,但t[3]=t[6]
(3)next[j] = k,模式串t中下标为j的字符,如果前k个字符相等,且t[j] != t[k](匹配不能夹带a[j])。1≤k
(4)next[j]=0,除(1)、(2)、(3)的其他情况。
设在字符串S中查找模式串T,若S[m]!=T[n],那么,取T[n]的模式函数值next[n]
(1) next[n]= -1 表示S[m]和T[0]间接比较过了,不相等,下一次比较 S[m+1] 和T[0];
(2) next[n]=0 表示比较过程中产生了不相等,下一次比较 S[m] 和T[0];
(3) next[n]= k >0 但k
入队时,直接压入stack1中
出队时,判断stack2是否为空,如果stack2为空,则将stack1中的元素倒入stack2中,否则直接弹出stack2中的元素
//入队操作
void EnQueue(stack &s1,stack &s2,int m)
{
s1.push(m);
}
//出队操作
void DeQueue(stack &s1,stack &s2,int &m)
{
if (s2.empty())
{
int p = s1.size();
for (int i=0;i
将queue1用作进栈出栈,queue2作为一个中转站
入栈时,直接压入queue1中
出栈时,先将queue1中的元素除最后一个元素外依次出队列,并压入队列queue2中,将留在queue1中的最后一个元素出队列即为出栈元素,最后还要把queue2中的元素再次压入queue1中
//进栈操作
void stackpush(queue &q1,queue &q2,int m)
{
q1.push(m);
}
//出栈操作
void stackpop(queue &q1,queue &q2,int &m)
{
int p = q1.size();
for (int i=0;i
高度和深度定义https://blog.csdn.net/bwh12398/article/details/78011819
https://blog.csdn.net/shixiaoguo90/article/details/23759887
如果结点中有一个指向父结点的指针,我们可以把问题转化为求两个链表的共同结点。
*poj2499
http://www.cnblogs.com/allensun/archive/2010/11/08/1872028.html