算法是码农的基本功,也是各个大厂必考察的重点,让我们一起坚持写算法题吧。
遇事不决,可问春风,春风不语,即是本心。
我们在我们能力范围内,做好我们该做的事,然后相信一切都事最好的安排就可以啦,慢慢来,会很快,向前走,别回头。
目录
1.合并两个有序链表
思路:while循环遍历链表,哪个值小则拼接哪一个即可。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode node = new ListNode(-1) ;
ListNode res = node ;
while(list1 != null && list2 != null){
if(list1.val <= list2.val){
node.next = new ListNode(list1.val) ;
list1 = list1.next ;
}else{
node.next = new ListNode(list2.val) ;
list2 = list2.next ;
}
node = node.next ;
}
if(list1 != null){
node.next = list1 ;
}
if(list2 != null){
node.next = list2 ;
}
return res.next ;
}
}
2.括号生成
思路:递归生成括号,先加左括号,当左括号小于n就可以加,右括号校友左括号就可以加右括号
class Solution {
public List<String> generateParenthesis(int n) {
List<String> list = new ArrayList<>() ;
dfs("",0,0,n,list) ;
return list ;
}
public void dfs(String s, int left, int right, int n, List<String> list){
if(right == n){
list.add(s) ;
}
if(left<n){
dfs(s+"(",left+1,right,n,list) ;
}
if(right < left){
dfs(s+")",left,right+1,n,list) ;
}
}
}
3.合并K个升序链表
思路:循环合并两个有序链表即可,思路就是合并两个有序链表,外层加一个循。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
ListNode res = null ;
for(ListNode list : lists){
res = mergeList(res,list) ;
}
return res ;
}
public ListNode mergeList(ListNode list1, ListNode list2){
ListNode list = new ListNode(-1) ;
ListNode res = list ;
while(list1 != null && list2 != null){
if(list1.val <= list2.val){
list.next = new ListNode(list1.val) ;
list1 = list1.next ;
}else{
list.next = new ListNode(list2.val) ;
list2 = list2.next ;
}
list = list.next ;
}
if(list1 != null){
list.next = list1 ;
}
if(list2 != null){
list.next = list2 ;
}
return res.next ;
}
}
4.两两交换链表中的节点
思路:本质上就是遍历然后修改指针位置使得链表节点的两两交换,需要保存前置节点,当前节点与下一节点,交换节点注意指针的覆盖。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode res = new ListNode(0) ;
res.next = head ;
ListNode tmp = res ;
while(tmp.next != null && tmp.next.next != null){
// 修改指针交换节点,需要先让3指向4,然后再用4指向3
ListNode start = tmp.next ;
ListNode end = tmp.next.next ;
// 2指向4
tmp.next = end ;
// 3指向4的后面一个
start.next = end.next ;
// 4指向3
end.next = start ;
// 往后走
tmp = start ;
}
return res.next ;
}
}
5.K个一组翻转链表
题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/reverse-nodes-in-k-group/description/
思路:长度大于K用栈模拟链表翻转,长于小于K用对队列模拟。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode res = new ListNode(0) ;
ListNode ans = res;
ListNode tail = head ;
LinkedList<Integer> stack = new LinkedList<>() ;
while(tail != null){
for(int i=0; i<k; i++){
// 长度不够k,模拟队列进行拼接
if(tail == null){
while(!stack.isEmpty()){
res.next = new ListNode(stack.removeLast()) ;
res = res.next ;
}
return ans.next ;
}
stack.push(tail.val) ;
tail = tail.next ;
}
// 长度够模拟栈进行拼接
while(!stack.isEmpty()){
res.next = new ListNode(stack.pop()) ;
res = res.next ;
}
}
return ans.next ;
}
}