算法是程序员的基本功,也是各个大厂必考察的重点,让我们一起坚持写算法题吧。
遇事不决,可问春风,春风不语,即是本心。
我们在我们能力范围内,做好我们该做的事,然后相信一切都事最好的安排就可以啦,慢慢来,会很快,向前走,别回头。
目录
1.最接近三数之和
2.电话号码的字母组合
3.四数之和
4.删除链表的倒数第 N 个结点
5.有效的括号
1.最接近三数之和
题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/3sum-closest/description/
思路:1.三层循环暴力法。
2.排序+双指针。
Java版:
class Solution {public int threeSumClosest(int[] nums, int target) {int min = Integer.MAX_VALUE ;int res = 0 ;for(int i=0; i<nums.length; i++){for(int j=i+1; j<nums.length; j++){for(int k=j+1; k<nums.length; k++){int abs = Math.abs(target -(nums[i] + nums[j] + nums[k]) ) ;if(abs < min){min = abs ;res = nums[i] + nums[j] + nums[k] ;}}}}return res ;}
}
class Solution {public int threeSumClosest(int[] nums, int target) {// 排序+双指针Arrays.sort(nums) ;int res = 0 ;int min = Integer.MAX_VALUE ;for(int i=0; i<nums.length-1; i++){int left = i+1, right = nums.length - 1 ;while(left < right){int sum = nums[i] + nums[left] + nums[right] ;int abs = Math.abs(sum - target) ;if(abs < min){min = abs ;res = sum ;}if(sum == target){return sum ;}else if(sum < target){left ++ ;}else{right -- ;}}}return res ;}
}
Python版:
class Solution:def threeSumClosest(self, nums: List[int], target: int) -> int:nums.sort() l = len(nums)res = 0 min = 1000000for i in range(l-2):left = i+1right = l - 1while(left < right):sum = nums[i] + nums[left] + nums[right]sub = abs(sum - target)if(sub < min):min = subres = sum if (sum == target):return sum elif(sum < target):left += 1else:right -= 1return res
Javascript版:
/*** @param {number[]} nums* @param {number} target* @return {number}*/
var threeSumClosest = function(nums, target) {// JS需要自定义排序规则,因为默认情况是按照字符串进行排序,而不是数值nums.sort(function(a,b){return a - b}) let res = 0 let min = 10000000for(let i=0; i<nums.length; i++){let left = i + 1, right = nums.length - 1while(left < right){const sum = nums[i] + nums[left] + nums[right] const abs = Math.abs(sum - target)if(abs < min){min = absres = sum }if(sum == target){return sum}else if(sum > target){right -- }else{left ++ }}}return res
};
2.电话号码的字母组合
题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/letter-combinations-of-a-phone-number/description/
思路:方法1:条件函数判断+字符串拼接
方法2:hashmap+dfs
Java版:
class Solution {public List<String> letterCombinations(String digits) {List<String> list = new ArrayList<>() ;String str = "" ;String [] arr = new String[4] ;Arrays.fill(arr,"") ;for(int i=0; i<digits.length(); i++){arr[i] = f(digits.charAt(i)) ;}for(int i=0; i<arr[0].length(); i++){if(arr[1].length()==0){StringBuilder sb = new StringBuilder("") ;sb.append(arr[0].charAt(i)) ;list.add(sb.toString()) ;}for(int j=0; j<arr[1].length(); j++){if(arr[2].length()==0){StringBuilder sb = new StringBuilder("") ;sb.append(arr[0].charAt(i)).append(arr[1].charAt(j)) ;list.add(sb.toString()) ; }for(int k=0; k<arr[2].length(); k++){if(arr[3].length()==0){StringBuilder sb = new StringBuilder("") ;sb.append(arr[0].charAt(i)).append(arr[1].charAt(j)).append(arr[2].charAt(k)) ;list.add(sb.toString()) ;}for(int l=0; l<arr[3].length(); l++){StringBuilder sb = new StringBuilder("") ;sb.append(arr[0].charAt(i)).append(arr[1].charAt(j)).append(arr[2].charAt(k)).append(arr[3].charAt(l)) ;list.add(sb.toString()) ;}}}}return list ;}
public static String f(char c){switch(c){case '2': return "abc";case '3': return "def";case '4': return "ghi";case '5': return "jkl"; case '6': return "mno";case '7': return "pqrs";case '8': return "tuv";case '9': return "wxyz";default : return "";}
}
}
class Solution {public List<String> letterCombinations(String digits) {List<String> list = new ArrayList<>() ;Map<Character,String> map = new HashMap<>() ;if(digits.length() == 0){return list ;}map.put('2',"abc") ;map.put('3',"def") ;map.put('4',"ghi") ;map.put('5',"jkl") ;map.put('6',"mno") ;map.put('7',"pqrs") ;map.put('8',"tuv") ;map.put('9',"wxyz") ;dfs(map,digits,0,list,new StringBuilder()) ;return list ;
}
public void dfs(Map<Character, String> map,String digits, int k, List<String> list, StringBuilder sb){if(k==digits.length()){list.add(sb.toString()) ;}else{String s = map.get(digits.charAt(k)) ;for(int i=0; i<s.length(); i++){sb.append(s.charAt(i)) ;dfs(map,digits,k+1,list,sb) ;sb.deleteCharAt(k) ;}}
}
}
Python版:
class Solution:def letterCombinations(self, digits: str) -> List[str]:list = []d = {}if len(digits) == 0:return listd['2'] = "abc"d['3'] = "def"d['4'] = "ghi"d['5'] = "jkl"d['6'] = "mno"d['7'] = "pqrs"d['8'] = "tuv"d['9'] = "wxyz"self.dfs(list,d,0,"",digits)return list def dfs(self, list, d, k, s,digits):if k == len(digits):list.append(s)else:tmp = d[digits[k]]for i in range(len(tmp)):s += tmp[i]self.dfs(list,d,k+1,s,digits)s = s[:k] + s[k+1:]
3.四数之和
题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/4sum/description/
思路:方法1:四层循环
方法2:排序+双指针+三层循环
Java版:
超时版:
class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> res = new ArrayList<>() ;for(int i=0; i<nums.length; i++){for(int j=i+1; j<nums.length; j++){for(int k=j+1; k<nums.length; k++){for(int l=k+1; l<nums.length; l++){if(target == (nums[i] + nums[j] + nums[k] + nums[l])){List<Integer> tmp = new ArrayList<>() ;tmp.add(nums[i]) ;tmp.add(nums[j]) ;tmp.add(nums[k]) ;tmp.add(nums[l]) ;Collections.sort(tmp) ;if(!res.contains(tmp)){res.add(tmp) ;}}}}}}return res ;}
}
击败5%的Java用户版:
class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> res = new ArrayList<>() ;Arrays.sort(nums) ;for(int i=0; i<nums.length; i++){for(int j=i+1; j<nums.length; j++){int left = j+1, right = nums.length - 1 ;while(left < right){// 防止超出整型最大范围long sum = (long)nums[i] + (long)nums[j] + (long)nums[left] + (long)nums[right] ;if(target == sum){List<Integer> tmp = new ArrayList<>() ;tmp.add(nums[i]) ;tmp.add(nums[j]) ;tmp.add(nums[left]) ;tmp.add(nums[right]) ;Collections.sort(tmp) ;if(!res.contains(tmp)){res.add(tmp) ;}right -- ;}else if(target > sum){left ++ ;}else{right -- ;}}}}return res ;}
}
击败50%的Java选手:
class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> res = new ArrayList<>() ;Arrays.sort(nums) ;for(int i=0; i<nums.length; i++){// 去重if(i>0 && nums[i] == nums[i-1]){continue ;}for(int j=i+1; j<nums.length; j++){// 去重if(j>i+1 && nums[j] == nums[j-1]){continue ;}int left = j+1, right = nums.length - 1 ;while(left < right){// 防止超出整型最大范围long sum = (long)nums[i] + (long)nums[j] + (long)nums[left] + (long)nums[right] ;if(target == sum){while(left < right && nums[left] == nums[left+1]){left ++ ;}while(left < right && nums[right] == nums[right-1]){right -- ;}List<Integer> tmp = new ArrayList<>() ;tmp.add(nums[i]) ;tmp.add(nums[j]) ;tmp.add(nums[left]) ;tmp.add(nums[right]) ;res.add(tmp) ;left ++ ;right -- ;}else if(target > sum){left ++ ;}else{right -- ;}}}}return res ;}
}
Python版:
class Solution:def fourSum(self, nums: List[int], target: int) -> List[List[int]]:res = []nums.sort()for i in range(0,len(nums)-2):if i>0 and nums[i] == nums[i-1]:continuefor j in range(i+1,len(nums)-1):if j>i+1 and nums[j] == nums[j-1]:continueleft = j + 1right = len(nums) - 1while left < right:sum = nums[i] + nums[j] + nums[left] + nums[right]if(sum == target):while(left < right and nums[left] == nums[left+1]):left += 1while(left < right and nums[right] == nums[right-1]):right -= 1res.append([nums[i],nums[j],nums[left],nums[right]])left += 1right -= 1elif(sum > target):right -= 1else:left += 1return res
Js版:
/*** @param {number[]} nums* @param {number} target* @return {number[][]}*/
var fourSum = function(nums, target) {nums.sort(function(a,b){return a - b })const res = []for(let i=0; i<nums.length; i++){if(i>0 && nums[i] == nums[i-1]){continue }for(let j=i+1; j<nums.length; j++){if(j>i+1 && nums[j] == nums[j-1]){continue}let left = j + 1, right = nums.length - 1while(left < right){const sum = nums[i] + nums[j] + nums[left] + nums[right] if(sum === target){while(left < right && nums[left] == nums[left+1]){left ++}while(left < right && nums[right] == nums[right-1]){right -- }res.push([nums[i],nums[j],nums[left],nums[right]])left ++ right --}else if(sum > target){right -- }else{left ++ }}}}return res
};
4.删除链表的倒数第 N 个结点
题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/remove-nth-node-from-end-of-list/description/
思路:先计算链表长度,然后找到相应的结点位置,修改指针即可。
/*** 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 removeNthFromEnd(ListNode head, int n) {// 找到倒数第n个节点,然后修改指针即可ListNode p = head ;int len = 0 ;while(p != null){len ++ ;p = p.next ;}if(n > len){return head ;}if(len==n){head = head.next ;return head ;}ListNode cur = head.next ;ListNode pre = head ;ListNode res = pre ;for(int i=0; i<len-n-1; i++){pre = pre.next ;cur = pre.next ;}pre.next = cur.next ;return res ;}
}
5.有效的括号
题目链接:. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/valid-parentheses/
思路:HashMap存储映射关系,栈模拟匹配括号匹配过程。
class Solution {public boolean isValid(String s) {Map<Character,Character> map = new HashMap<>() ;map.put('{','}') ;map.put('(',')') ;map.put('[',']') ;LinkedList<Character> stack = new LinkedList<>() ;for(int i=0; i<s.length(); i++){char c = s.charAt(i) ;if(c == '{' || c == '(' || c == '['){stack.push(c) ;}else{// 没有匹配的左括号,右括号多if(stack.isEmpty()){return false ;}char top = stack.pop() ;if(s.charAt(i) != map.get(top)){return false ;}}}// 栈不空,说明左括号多,没匹配if(stack.isEmpty() == false){return false ;}return true ;}
}