算法是程序员的基本功,也是各个大厂必考察的重点,让我们一起坚持写算法题吧。
遇事不决,可问春风,春风不语,即是本心。
我们在我们能力范围内,做好我们该做的事,然后相信一切都事最好的安排就可以啦,慢慢来,会很快,向前走,别回头。
目录
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 = 1000000
for i in range(l-2):
left = i+1
right = l - 1
while(left < right):
sum = nums[i] + nums[left] + nums[right]
sub = abs(sum - target)
if(sub < min):
min = sub
res = sum
if (sum == target):
return sum
elif(sum < target):
left += 1
else:
right -= 1
return 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 = 10000000
for(let i=0; i<nums.length; i++){
let left = i + 1, right = nums.length - 1
while(left < right){
const sum = nums[i] + nums[left] + nums[right]
const abs = Math.abs(sum - target)
if(abs < min){
min = abs
res = 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 list
d['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]:
continue
for j in range(i+1,len(nums)-1):
if j>i+1 and nums[j] == nums[j-1]:
continue
left = j + 1
right = len(nums) - 1
while left < right:
sum = nums[i] + nums[j] + nums[left] + nums[right]
if(sum == target):
while(left < right and nums[left] == nums[left+1]):
left += 1
while(left < right and nums[right] == nums[right-1]):
right -= 1
res.append([nums[i],nums[j],nums[left],nums[right]])
left += 1
right -= 1
elif(sum > target):
right -= 1
else:
left += 1
return 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 - 1
while(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 ;
}
}