Leetcode面T10(1-9)数组

Q10.1 合并排序的数组

给定两个排序后的数组 A 和 B,其中 A 的末端有足够的缓冲空间容纳 B。 编写一个方法,将 B 合并入 A 并排序。

初始化 A 和 B 的元素数量分别为 m 和 n。

示例:

输入:
A = [1,2,3,0,0,0], m = 3
B = [2,5,6],       n = 3

输出: [1,2,2,3,5,6]
说明:

A.length == n + m

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sorted-merge-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

Java 原地逆序归并 O(N)

class Solution {
    public void merge(int[] A, int m, int[] B, int n) {
        int i = m - 1, j = n - 1, idx = m + n - 1;
        while (j >= 0) {
            if (i < 0 || B[j] >= A[i]) {
                A[idx--] = B[j--];
            } else {
                A[idx--] = A[i--];
            } 
        }
    }
}

Q10.2 合并排序的数组

编写一种方法,对字符串数组进行排序,将所有变位词组合在一起。变位词是指字母相同,但排列不同的字符串。

注意:本题相对原题稍作修改

示例:

输入: ["eat", "tea", "tan", "ate", "nat", "bat"],
输出:
[
  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]
说明:

所有输入均为小写字母。
不考虑答案输出的顺序。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/group-anagrams-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

public class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        if(strs==null||strs.length==0) return null;
        HashMap<String,List<String>> map = new HashMap<>();
        //遍历所有字符串
        for (String str : strs) {
            char[] chars = str.toCharArray();
            //对每一个字符串进行排序,乱序后再排序后的字符串肯定都是一样的,直接用这个作为Key存入map中
            Arrays.sort(chars);
            String key = new String(chars);
            List<String> list = null;
            //取key对应的value
            if(!map.containsKey(key)) {
                list = new ArrayList<>();
            }else {
                list = map.get(key);
            }
            list.add(str);
            map.put(key,list);
        }
        return new ArrayList<>(map.values());
    }
}

Q10.3 搜索旋转数组

搜索旋转数组。给定一个排序后的数组,包含n个整数,但这个数组已被旋转过很多次了,次数不详。请编写代码找出数组中的某个元素,假设数组元素原先是按升序排列的。若有多个相同元素,返回索引值最小的一个。

示例1:

 输入: arr = [15, 16, 19, 20, 25, 1, 3, 4, 5, 7, 10, 14], target = 5
 输出: 8(元素5在该数组中的索引)
示例2:

 输入:arr = [15, 16, 19, 20, 25, 1, 3, 4, 5, 7, 10, 14], target = 11
 输出:-1 (没有找到)
提示:

arr 长度范围在[1, 1000000]之间

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-rotate-array-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
    public int search(int[] arr, int target) {
        for (int i = 0; i < arr.length; i++) {
            if (arr[i]==target){
                return i;
            }
        }
        return -1;
    }
}

Q10.5 稀疏数组搜索

稀疏数组搜索。有个排好序的字符串数组,其中散布着一些空字符串,编写一种方法,找出给定字符串的位置。

示例1:

 输入: words = ["at", "", "", "", "ball", "", "", "car", "", "","dad", "", ""], s = "ta"
 输出:-1
 说明: 不存在返回-1。
示例2:

 输入:words = ["at", "", "", "", "ball", "", "", "car", "", "","dad", "", ""], s = "ball"
 输出:4
提示:

words的长度在[1, 1000000]之间

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sparse-array-search-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

在Java中判断字符串值是否相等用s1,equals(s1)。不要直接用==,被耗了好长时间mmp.

class Solution {
    //直接法
    // public int findString(String[] words, String s) {
    //     for(int i =0;i <words.length;i++){
    //         if(words[i].equals(s)){
    //             return i;
    //         }
    //     }
    //     return -1;
    // }
    //二分搜索法
    public int findString(String[] words, String s) {
        //直接二分搜索
        int left = 0;
        int right = words.length - 1;
        //[left.right)
        while(left <= right){

            while(left < words.length && words[left].equals("")){
                left++;
            }
            while(right >= 0  && words[right].equals("")){
                right--;
            }
            int mid = left + (right - left) / 2;
            while(mid < words.length && words[mid].equals("")){
                mid++;
            }
            if(words[mid].equals(s)){
                return mid;
            }else if(words[mid].compareTo(s) > 0){
                //收缩右边界,锁定左边界
                right = mid - 1;
            }else if(words[mid].compareTo(s) < 0){
                //收缩左边界,锁定右边界
                left = mid + 1;
            }
        }
        return -1;
    }
}

Q10.9 排序矩阵查找

给定M×N矩阵,每一行、每一列都按升序排列,请编写代码找出某元素。

示例:

现有矩阵 matrix 如下:

[
  [1,   4,  7, 11, 15],
  [2,   5,  8, 12, 19],
  [3,   6,  9, 16, 22],
  [10, 13, 14, 17, 24],
  [18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。

给定 target = 20,返回 false。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sorted-matrix-search-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        if (matrix == null || matrix.length == 0) {
            return false;
        }
        int m = matrix.length, n = matrix[0].length, row = 0, col = n - 1;
        while (row < m && col >= 0) {
            if (matrix[row][col] < target) {
                row++;
            } else if(matrix[row][col] > target) {
                col--;
            } else {
                return true;
            }
        }

        return false;
    }
}

Q10.10 数字流的秩

假设你正在读取一串整数。每隔一段时间,你希望能找出数字 x 的秩(小于或等于 x 的值的个数)。请实现数据结构和算法来支持这些操作,也就是说:

实现 track(int x) 方法,每读入一个数字都会调用该方法;

实现 getRankOfNumber(int x) 方法,返回小于或等于 x 的值的个数。

注意:本题相对原题稍作改动

示例:

输入:
["StreamRank", "getRankOfNumber", "track", "getRankOfNumber"]
[[], [1], [0], [0]]
输出:
[null,0,null,1]
提示:

x <= 50000
track 和 getRankOfNumber 方法的调用次数均不超过 2000 次

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rank-from-stream-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

int[] nums;
    public StreamRank() {

        nums = new int[50002];
    }
    
    public void track(int x) {

        // 避免为0
        ++x;
        for (int i = x; i <= nums.length - 1; i += lowBit(i))
            nums[i]++;
    }
    
    public int getRankOfNumber(int x) {

        int sum = 0;
        ++x;
        for (int i = x; i > 0; i -= lowBit(i))
            sum += nums[i];
        
        return sum;
    }

    public int lowBit(int x) {

        return x & (-x);
    }

Q10.11 峰与谷

在一个整数数组中,“峰”是大于或等于相邻整数的元素,相应地,“谷”是小于或等于相邻整数的元素。例如,在数组{5, 8, 4, 2, 3, 4, 6}中,{8, 6}是峰, {5, 2}是谷。现在给定一个整数数组,将该数组按峰与谷的交替顺序排序。

示例:

输入: [5, 3, 1, 2, 3]
输出: [5, 1, 3, 2, 3]
提示:

nums.length <= 10000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/peaks-and-valleys-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

贪心,参考题解:

(1)如果i为峰的位置,则判断当前位置是否小于前一个位置(前一个为谷),若小于,则交换,大于则不处理。即: if(nums[i]<nums[i-1]) swap(nums[i],nums[i-1]);

(2)如果i为谷的位置,则判断当前位置是否大于前一个位置(前一个为峰),若大于,则交换,大于则不处理。即: if(nums[i]>nums[i-1]) swap(nums[i],nums[i-1]);

public void wiggleSort(int[] nums) {
	/*     对数组排序 O(nlogn)
	int[] res = Arrays.copyOf(nums, nums.length);
	Arrays.sort(res);
	int index = res.length - 1;
	for(int i = 0;i < res.length;i += 2) {
		nums[i] = res[index--];
	}
	for(int i = 1;i < res.length;i += 2) {
		nums[i] = res[index--];
	}
	*/
        // 直接遍历 O(n)
	for(int i = 1;i < nums.length;i++) {
		if(i % 2 == 1) {
			if(nums[i] > nums[i - 1]) {
				int temp = nums[i];
				nums[i] = nums[i - 1];
				nums[i - 1] = temp;
			}
		}else {
			if(nums[i] < nums[i - 1]) {
				int temp = nums[i];
				nums[i] = nums[i - 1];
				nums[i - 1] = temp;
			}
		}

	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值