chefyuan 2021-05-05 13:49:56 +08:00
commit f765951ec7
15 changed files with 627 additions and 12 deletions

View File

@ -33,6 +33,8 @@
****
```java
class Solution {
public boolean isPalindrome(ListNode head) {
@ -72,6 +74,10 @@ class Solution {
![](https://cdn.jsdelivr.net/gh/tan45du/photobed@master/photo/翻转链表部分.1v2ncl72ligw.gif)
#### ****
Java Code
```java
class Solution {
public boolean isPalindrome(ListNode head) {
@ -129,3 +135,63 @@ class Solution {
}
```
C++ Code
```cpp
class Solution {
public:
bool isPalindrome(ListNode* head) {
if (head == nullptr || head->next == nullptr) {
return true;
}
//找到中间节点,也就是翻转的头节点,这个在昨天的题目中讲到
//但是今天和昨天有一些不一样的地方就是,如果有两个中间节点返回第一个,昨天的题目是第二个
ListNode * midenode = searchmidnode(head);
//原地翻转链表,需要两个辅助指针。这个也是面试题目,大家可以做一下
//这里我们用的是midnode->next需要注意因为我们找到的是中点但是我们翻转的是后半部分
ListNode * backhalf = reverse(midenode->next);
//遍历两部分链表,判断值是否相等
ListNode * p1 = head;
ListNode * p2 = backhalf;
while (p2 != nullptr) {
if (p1->val != p2->val) {
return false;
}
p1 = p1->next;
p2 = p2->next;
}
// 还原链表并返回结果,这一步是需要注意的,我们不可以破坏初始结构,我们只是判断是否为回文,
//当然如果没有这一步也是可以AC但是面试的时候题目要求可能会有这一条。
midenode->next = reverse(backhalf);
return true;
}
//找到中间的部分
ListNode * searchmidnode (ListNode * head) {
ListNode * fast = new ListNode(-1);
ListNode * slow = new ListNode(-1);
fast = head;
slow = head;
//找到中点
while (fast->next != nullptr && fast->next->next != nullptr) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
//翻转链表
ListNode * reverse (ListNode * slow) {
ListNode * low = nullptr;
ListNode * temp = nullptr;
//翻转链表
while (slow != nullptr) {
temp = slow->next;
slow->next = low;
low = slow;
slow = temp;
}
return low;
}
};
```

View File

@ -72,3 +72,24 @@ var hasCycle = function(head) {
return false;
};
```
C++ Code:
```cpp
class Solution {
public:
bool hasCycle(ListNode *head) {
ListNode * fast = head;
ListNode * low = head;
while (fast != nullptr && fast->next != nullptr) {
fast = fast->next->next;
low = low->next;
if (fast == low) {
return true;
}
}
return false;
}
};
```

View File

@ -123,7 +123,9 @@ public class Solution {
![2](https://cdn.jsdelivr.net/gh/tan45du/photobed@master/photo/环形链表2.elwu1pw2lw0.gif)
****
Java Code:
```java
public class Solution {
@ -153,3 +155,34 @@ public class Solution {
}
```
C++ Code:
```cpp
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
//快慢指针
ListNode * fast = head;
ListNode * low = head;
//设置循环条件
while (fast != nullptr && fast->next != nullptr) {
fast = fast->next->next;
low = low->next;
//相遇
if (fast == low) {
//设置一个新的指针从头节点出发慢指针速度为1所以可以使用慢指针从相遇点出发
ListNode * newnode = head;
while (newnode != low) {
low = low->next;
newnode = newnode->next;
}
//在环入口相遇
return low;
}
}
return nullptr;
}
};
```

View File

@ -82,6 +82,8 @@
****
Java Code:
```java
class Solution {
public ListNode insertionSortList(ListNode head) {
@ -121,7 +123,45 @@ class Solution {
}
```
C++ Code:
```cpp
class Solution {
public:
ListNode* insertionSortList(ListNode* head) {
if (head == nullptr && head->next == nullptr) {
return head;
}
//哑节点
ListNode * dummyNode = new ListNode(-1);
dummyNode->next = head;
//pre负责指向新元素last 负责指向新元素的前一元素
//判断是否需要执行插入操作
ListNode * pre = head->next;
ListNode * last = head;
ListNode * temphead = dummyNode;
while (pre != nullptr) {
//不需要插入到合适位置,则继续往下移动
if (last->val <= pre->val) {
pre = pre->next;
last = last->next;
continue;
}
//开始出发,查找新元素的合适位置
temphead = dummyNode;
while (temphead->next->val <= pre->val) {
temphead = temphead->next;
}
//此时我们已经找到了合适位置,我们需要进行插入,大家可以画一画
last->next = pre->next;
pre->next = temphead->next;
temphead->next = pre;
pre = last->next;
}
return dummyNode->next;
}
};
```

View File

@ -33,6 +33,10 @@ low = temp 即可。然后重复执行上诉操作直至最后,这样则完成
****
Java Code:
```java
class Solution {
@ -81,8 +85,44 @@ var reverseList = function(head) {
};
```
C++
```cpp
class Solution {
public:
ListNode* reverseList(ListNode* head) {
//特殊情况
if (head == nullptr || head->next == nullptr) {
return head;
}
//反转
return reverse(head);
}
ListNode * reverse (ListNode * head) {
ListNode * low = nullptr;
ListNode * pro = head;
while (pro != nullptr) {
//代表橙色指针
ListNode * temp = pro;
//移动绿色指针
pro = pro->next;
//反转节点
temp->next = low;
//移动黄色指针
low = temp;
}
return low;
}
};
```
****
Java Code:
```java
class Solution {
@ -118,3 +158,26 @@ var reverseList = function(head) {
};
```
C++:
```cpp
class Solution {
public:
ListNode * reverseList(ListNode * head) {
//结束条件
if (head == nullptr || head->next == nullptr) {
return head;
}
//保存最后一个节点
ListNode * pro = reverseList(head->next);
//将节点进行反转。我们可以这样理解 4->next->next = 4;
//4->next = 5
//则 5->next = 4 则实现了反转
head->next->next = head;
//防止循环
head->next = nullptr;
return pro;
}
};
```

View File

@ -36,6 +36,8 @@
####
Java Code:
```java
class Solution {
public ListNode oddEvenList(ListNode head) {
@ -60,3 +62,30 @@ class Solution {
}
```
C++ Code:
```cpp
class Solution {
public:
ListNode* oddEvenList(ListNode* head) {
if (head == nullptr || head->next == nullptr) {
return head;
}
ListNode * odd = head;
ListNode * even = head->next;
ListNode * evenhead = even;
while (odd->next != nullptr && even->next != nullptr) {
//将偶数位合在一起,奇数位合在一起
odd->next = even->next;
odd = odd->next;
even->next = odd->next;
even = even->next;
}
//链接
odd->next = evenhead;
return head;
}
};
```

View File

@ -39,6 +39,10 @@
![2](https://cdn.jsdelivr.net/gh/tan45du/photobed@master/photo/删除重复节点2.3btmii5cgxa0.gif)
****
Java Code:
```java
class Solution {
public ListNode deleteDuplicates(ListNode head) {
@ -68,3 +72,35 @@ class Solution {
}
```
C++ Code:
```cpp
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if(head == nullptr || head->next == nullptr){
return head;
}
ListNode * pre = head;
ListNode * low = new ListNode(0);
low->next = pre;
ListNode * ret = new ListNode(-1);
ret = low;
while(pre != nullptr && pre->next != nullptr) {
if (pre->val == pre->next->val) {
while (pre != nullptr && pre->next != nullptr && pre->val == pre->next->val) {
pre = pre->next;
}
pre = pre->next;
low->next = pre;
}
else{
pre = pre->next;
low = low->next;
}
}
return ret->next;
}
};
```

View File

@ -34,6 +34,8 @@
****
Java Code:
```java
/**
* Definition for singly-linked list.
@ -75,7 +77,41 @@ class Solution {
}
```
C++ Code:
```cpp
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
if (head == nullptr) {
return head;
}
ListNode * pro = head;
ListNode * big = new ListNode(-1);
ListNode * small = new ListNode(-1);
ListNode * headbig = big;
ListNode * headsmall =small;
//分
while (pro != nullptr) {
//大于时,放到 big 链表上
if (pro->val >= x) {
big->next = pro;
big = big->next;
// 小于放到 small 链表上
}else {
small->next = pro;
small = small->next;
}
pro = pro->next;
}
//细节
big->next = nullptr;
//合
small->next = headbig->next;
return headsmall->next;
}
};
```

View File

@ -34,6 +34,12 @@
****
Java Code:
```java
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
@ -79,3 +85,47 @@ class Solution {
}
```
C++ Code:
```cpp
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int left, int right) {
ListNode * temp = new ListNode(-1);
temp->next = head;
ListNode * pro = temp;
//来到 left 节点前的一个节点
int i = 0;
for (; i < left-1; ++i) {
pro = pro->next;
}
// 保存 left 节点前的第一个节点
ListNode * leftNode = pro;
for (; i < right; ++i) {
pro = pro->next;
}
// 保存 right 节点后的节点
ListNode * rightNode = pro->next;
//切断链表
pro->next = nullptr;
ListNode * newhead = leftNode->next;
leftNode->next = nullptr;
leftNode->next = rever(newhead);
//重新接头
newhead->next = rightNode;
return temp->next;
}
ListNode * rever (ListNode * head) {
ListNode * low = nullptr;
ListNode * pro = head;
while (pro != nullptr) {
ListNode * temp = pro;
pro = pro->next;
temp->next = low;
low = temp;
}
return low;
}
};
```

View File

@ -26,14 +26,18 @@
### HashSet
HashsetHashset
****
Java Code
```java
public class Solution {
public ListNode getIntersectionNode (ListNode headA, ListNode headB) {
ListNode tempa = headA;
ListNode tempb = headB;
//定义hash表
//定义Hashset
HashSet<ListNode> arr = new HashSet<ListNode>();
while (tempa != null) {
arr.add(tempa);
@ -45,12 +49,36 @@ public class Solution {
}
tempb = tempb.next;
}
return tempb;
return tempb;
}
}
```
C++ Code:
```cpp
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode * tempa = headA;
ListNode * tempb = headB;
//定义Hashset, cpp对应set
set <ListNode *> arr;
while (tempa != nullptr) {
arr.insert(tempa);
tempa = tempa->next;
}
while (tempb != nullptr) {
if (arr.find(tempb) != arr.end()) {
return tempb;
}
tempb = tempb->next;
}
return tempb;
}
};
```
@ -59,6 +87,10 @@ public class Solution {
****
Java Code
```java
public class Solution {
public ListNode getIntersectionNode (ListNode headA, ListNode headB) {
@ -76,7 +108,25 @@ public class Solution {
}
```
C++ Code
```cpp
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
//定义两个节点
ListNode * tempa = headA;
ListNode * tempb = headB;
//循环
while (tempa != tempb) {
//如果不为空就指针下移,为空就跳到另一链表的头部
tempa = tempa != nullptr ? tempa->next: headB;
tempb = tempb != nullptr ? tempb->next: headA;
}
return tempa;
}
};
```

View File

@ -27,8 +27,13 @@
![](https://cdn.jsdelivr.net/gh/tan45du/photobed@master/photo/合并数组.216f4nn4lti8.gif)
****
Java Code:
```java
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode headpro = new ListNode(-1);
ListNode headtemp = headpro;
while (l1 != null && l2 != null) {
@ -45,7 +50,33 @@
}
headpro.next = l1 != null ? l1:l2;
return headtemp.next;
}
}
```
C++ Code:
```cpp
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode * headpro = new ListNode(-1);
ListNode * headtemp = headpro;
while (l1 != nullptr && l2 != nullptr) {
//接上大的那个
if (l1->val >= l2->val) {
headpro->next = l2;
l2 = l2->next;
}
else {
headpro->next = l1;
l1 = l1->next;
}
headpro = headpro->next;
}
headpro->next = l1 != nullptr ? l1: l2;
return headtemp->next;
}
};
```

View File

@ -26,14 +26,20 @@
### HashSet
HashsetHashset
****
Java Code:
```java
public class Solution {
public ListNode getIntersectionNode (ListNode headA, ListNode headB) {
ListNode tempa = headA;
ListNode tempb = headB;
//定义hash表
//定义Hashset
HashSet<ListNode> arr = new HashSet<ListNode>();
while (tempa != null) {
arr.add(tempa);
@ -51,6 +57,31 @@ public class Solution {
}
```
C++ Code:
```cpp
class Solution {
public:
ListNode * getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode * tempa = headA;
ListNode * tempb = headB;
//定义Hashset
set <ListNode *> arr;
while (tempa != nullptr) {
arr.insert(tempa);
tempa = tempa->next;
}
while (tempb != nullptr) {
if (arr.find(tempb) != arr.end()) {
return tempb;
}
tempb = tempb->next;
}
return tempb;
}
};
```
@ -59,6 +90,12 @@ public class Solution {
****
Java Code:
```java
public class Solution {
public ListNode getIntersectionNode (ListNode headA, ListNode headB) {
@ -68,15 +105,33 @@ public class Solution {
//循环
while (tempa != tempb) {
//如果不为空就指针下移,为空就跳到另一链表的头部
tempa = tempa!=null ? tempa.next:headB;
tempb = tempb!=null ? tempb.next:headA;
tempa = tempa != null ? tempa.next: headB;
tempb = tempb != null ? tempb.next: headA;
}
return tempa;
}
}
```
C++ Code:
```cpp
class Solution {
public:
ListNode * getIntersectionNode(ListNode *headA, ListNode *headB) {
//定义两个节点
ListNode * tempa = headA;
ListNode * tempb = headB;
//循环
while (tempa != tempb) {
//如果不为空就指针下移,为空就跳到另一链表的头部
tempa = tempa != nullptr ? tempa->next: headB;
tempb = tempb != nullptr ? tempb->next: headA;
}
return tempa;
}
};
```

View File

@ -30,6 +30,10 @@
****
Java Code:
```java
class Solution {
public ListNode getKthFromEnd (ListNode head, int k) {
@ -58,3 +62,34 @@ class Solution {
}
```
C++ Code:
```cpp
class Solution {
public:
ListNode * getKthFromEnd(ListNode * head, int k) {
//特殊情况
if (head == nullptr) {
return head;
}
//初始化两个指针
ListNode * pro = new ListNode(-1);
ListNode * after = new ListNode(-1);
//定义指针指向
pro = head;
after = head;
//先移动绿指针到指定位置
for (int i = 0; i < k-1; i++) {
pro = pro->next;
}
//两个指针同时移动
while (pro->next != nullptr) {
pro = pro->next;
after = after->next;
}
//返回倒数第k个节点
return after;
}
};
```

View File

@ -48,6 +48,10 @@
![](https://img-blog.csdnimg.cn/20210321131249789.gif)
****
Java Code:
```java
class Solution {
public ListNode middleNode(ListNode head) {
@ -64,3 +68,21 @@ class Solution {
}
```
C++ Code:
```cpp
public:
ListNode* middleNode(ListNode* head) {
ListNode * fast = head;//快指针
ListNode * slow = head;//慢指针
//循环条件,思考一下跳出循环的情况
while (fast != nullptr && fast->next != nullptr) {
fast = fast->next->next;
slow = slow->next;
}
//返回slow指针指向的节点
return slow;
}
};
```

View File

@ -69,6 +69,12 @@
nlist1summod1
****
Java Code:
```java
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
@ -108,3 +114,45 @@ class Solution {
}
```
C++ Code:
```cpp
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
//返回链表
ListNode * nList = new ListNode(-1);
ListNode * tempnode = nList;
//用来保存进位值初始化为0
int summod = 0;
while(l1 != nullptr || l2 != nullptr) {
//如果l1的链表为空则l1num为0若是不为空则为链表的节点值
//判断是否为空为空就设为0
int l1num = l1 == nullptr ? 0 : l1->val;
int l2num = l2 == nullptr ? 0 : l2->val;
//将链表的值和进位值相加,得到为返回链表的值
int sum = l1num + l2num + summod;
//更新进位值例18/10=19/10=0
summod = sum / 10;
//新节点保存的值18 % 8=2则添加2
sum = sum % 10;
//添加节点
tempnode->next = new ListNode(sum);
//移动指针
tempnode = tempnode->next;
if (l1 != nullptr) {
l1 = l1->next;
}
if (l2 != nullptr) {
l2 = l2->next;
}
}
//最后根据进位值判断需不需要继续添加节点
if (summod == 1) {
tempnode->next = new ListNode(summod);
}
return nList->next;
}
};
```