数据结构与算法第四篇

链表和数组的高频面试题

 

数组高频面试题

 

No.1(LeetCode1:两个数之和)

题:给定一个非负整数的数组,给定一个target,如果数组中有两个元素相加的和等于target,那么返回这两个数的下标。

代码:本题思路,不使用暴力解法,通过使用空间换时间的方式来求解

public class Solution{
    public int [] twoSum(int [] nums,int target){
        // 构建缓存器,用来存储nums中的数据。
        Map<Integer,Integer> cache = new HashMap();
        for(int i = 0;i<nums.length;i++){
             // 判断缓存中是否有另一半
        if(cache.containsKey(target-nums[i])){
            return new int[]{cache.get(target-nums[i]),i}
        }else{
            cache.put(nums[i],i);
        }
        }
       return null;
    }
}

思路分析:此题用的思想就是用空间来替换运行时间,遍历整个数组以后,在数组寻找target-nums[i]这个数,如果找到了,返回这两个数在数组中的下标,如果没有找到,则将i下标的数存入缓存器中,妙啊!

No.2(leetCode15:三数之和)

题:给定一个包含N个整数的数组nums,判断nums中是否存在三个元素a,b,c,使得a+b+c=0?,找出所有和为0且不重复的三元组。

思路:使用三指针思想,定义三指针i,j,k,这里用的一个比较重要的思想就是剪枝,就是一开始就过滤到一些不满足题目意思的案例,这个题目我打算手写一遍,加深一下代码印象和理解程度。

public class Solution{
    public List<List<Integer>> threeNumberSum(int arr[]){
        // 首先进行数组的长度和非空判断
        if(arr == null || arr.length<3){
            // 直接返回一个空的集合
            return new ArrayList();
        }
        // 排序数组
        Arrays.sort(arr);
        // 定义存储集合的集合
        List<List<Integer>> res = new ArrayList();
        // 循环遍历
        for(int i = 0;i<arr.length<2;i++){
        // 去重第一步,如果i下标走到i+1的位置发现下标对应的数相等
            if(i>0&& arr[i]==arr[i-1]){
                    continue;
               }
           // 条件判断
            if(arr[i]>0){
                break;
            }
            // 定义三指针了
            int j = i+1;
            int k = arr.length-1;
           	while(j<k){
                int a = arr[i];
                int b = arr[j];
                int c = arr[k];
                // 判断三个数之和是否为0
                if((a+b+c)==0){
                    // 定义集合来存三个数
                    List<Integer> list = new ArrayList();
                    list.add(a);
                    list.add(b);
                    list.add(c);
                    // 在循环外定义好存储集合的集合
                    res.add(list);
                    
                    // 添加后进一步排出重复的情况
                    while(j<k&&arr[j]==arr[j+1]){
                        j++;
                    }
                    
                    while(j<k&&arr[k]==arr[k-1]){
                        k--;
                    }
                    // 排出后让指针继续走
                    j++;
                    k--;
                }else if((a+b+c>0)){
                    // 让k指针前移,数大了。
                    k--;
                }else{
                    j++;
                }
            }
            
        }
        // 返回最终需要的集合
      return res;
    }
}

总结:写了几题后发现代码思路真的很关键,是非常关键,没有思路,是根本写不出代码的!

No.3(LeetCode-LCP18寻找匹配的早餐组合)

思路:同样是先排序,利用双指针思想。

代码:

public class Solution{
    public int findArray(int [] staple,int [] drinks,int x){
        // 排序
        Arrays.sort(staple);
        Arrays.sort(drinks);
        
        // 定义符合题目组合的变量res
        int  res = 0;
        
        // 定义双指针
        int i = 0;
        int j = drinks.length-1;
        // 判断
        while(i<staple.length&&j>=0){
            // 判断
            if*(staple[i] + drinks[j] <= x){
                res = (res+j+1)%1000000007;//取模是防止数据溢出
                i++;
            }else{
                // 如果结果大于x说明j索引位置上的数太大了,需要让j指针往前移。
                j--;
            }
        }
        return res;
        
    }
}

对于数组的算法练习题还有很多,写出题号,后面去LeetCode上刷。

LeetCode 88 合并两个有序数组

LeetCode 66 加一

LeetCode 9 回文数

LeetCode 18 四数之和

LeetCode 26 删除排序数组中的重复项

LeetCode 189 旋转数组 p

 

链表高频面试题

No.1(LeetCode 24: 两两交换链表中的节点)

给定一个链表,两两交换其中相邻的节点,并返回交换后的节点。

解题思路:

交换节点就需要在真实的链表中将链表中的值进行交换,此题解题思路亮点就是构建哨兵,考虑到要是链表中的头节点就是要交换的节点,构造一个哨兵节点,并且一开始就要记录哨兵的值,然后将哨兵这个下个节点返回,就能得到交换节点后的链表。

public class Solution{
		public ListNode swapPairs(ListNode head){
				// 特殊判断
				if(head == null || head.next == null){
							return head;
				}
				// 定义指针
				ListNode curr = head;
				ListNode prev = new ListNode(-1);
				// 将哨兵指向curr指针
				prev.next = curr;
				// 提前记录好哨兵节点
				ListNode p = prev;
				
				
				// 循环开始,交换节点。
				while(curr != null &&  curr.next != null){
						ListNode next = curr.next;
						ListNode next_next = next.next;
						
						// 交换节点
						next.next = curr;
						prev.next = next;
						curr.next = next_next;
						
						// 节点下跳
						prev = curr;
						curr = next_next;
						
				}
				return p.next;
		}
}

No.2 (LeetCode 142:环形链表 ||)

No.3 (LeetCode 21:合并两个有序链表)

No.4 (LeetCode 25:k个一组翻转链表 )

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值