编程语言
首页 > 编程语言> > 算法比赛初赛解答

算法比赛初赛解答

作者:互联网

第一题https://leetcode-cn.com/problems/implement-strstr/
解法一:BF算法,即直接暴力求解
代码部分:public static int strStr(String haystack,String needle){
int hlen = haystack.length();
int nlen = needle.length();
int i = 0,j = 0;
while(i < hlen && j < nlen){
if(haystack.charAt(i) == needle.charAt(j)){
i++;j++; //若一直接相等,则继续遍历
}else{
i = i-(j-1); //若不等时,则haystack直接原地不动
j=0; //needle回到0位置
}
}
if(j == nlen){
return i-j;
}else {
return -1;
}
}

解法二:KMP算法,即求出next数组,利用next数组进行求解
代码部分//KMP算法
public int getIndex(String s1,String s2) {
if(s1 == null || s2 == null || s1.length() == 0 || s2.length() == 0 ||s2.length() > s1.length()){
return 0;
}
char[] chs1 = s1.toCharArray();
char[] chs2 = s2.toCharArray();
int c1 = 0;
int c2 = 0;
int[] next = getNextArr(chs2);
while (c1 < chs1.length && c2 < chs2.length) {
if(chs1[c1] == chs2[c2]) {
c1++;c2++;//相等时直接两指针向后移即可
}else if(next[c2] == -1 /*c2 == 0/) { //s1中的对比位置无法继续往前跳了
c1++;
}else{
c2 = next[c2];
}
}
//c1越界或c2越界
return c2 == chs2.length ? c1 - c2 : -1;
}

//ababddsas
private int[] getNextArr(char[] chs2) {
if(chs2.length == 1){
return new int[]{-1};
}
int[] next = new int[chs2.length];
next[0] = -1;
next[1] = 0;
int cur = 2; //next数组初始位置
int pos = 0; //哪个位置的字符和cur进行比较,pos即是cur位置的next值,又是chs位置的比较量
while(cur < next.length) {
if(chs2[cur-1] == chs2[pos]){
next[cur++] = ++pos;
}else if(pos > 0){ //当跳到pos位置的字符,和cur-1的字符匹配不上
pos = next[pos];
}else{
next[cur++] = 0;
}
}
return next;
}

第二题:https://leetcode-cn.com/problems/length-of-last-word/
解法一:利用栈栈,当把字符串完全装进去之后,我们通过弹栈的做法将最后一个单词后面的空格完全弹出
代码部分:public int lengthOfLastWord(String s) {
int count=1;
Stack stack=new Stack();
char[] ss=s.toCharArray();
for(int i=0;i<ss.length;i++){
stack.push(ss[i]);
}
// 清理空格
while(stack.pop()==’ ‘);
while(!stack.isEmpty()&&stack.pop()!=’ ') count++;
return count;
}

解法二:反向遍历,第一个空格时停下即可
public static int getlen(String string){
int index = string.length() - 1;
while(string.charAt(index) == ’ '){
index–;
}
int count = 0;
while(index >= 0 && string.charAt(index) != ’ '){
count++;
index–;
}
return count;
}

第三题:https://leetcode-cn.com/problems/valid-palindrome/solution/
yan-zheng-hui-wen-chuan-by-le etcode-solution/
解法一:双指针
public boolean isPalindrome(String s){
if (s == null || s == “”) { //判断字符串是否空
return true;
}
//两头开始
int left = 0, right = s.length() - 1;
while (left <= right) {
while (left < right && !Character.isLetterOrDigit(s.charAt(left))) {
left++;
}
while (left < right && !Character.isLetterOrDigit(s.charAt(right))) {
right–;
}
if ((Character.toLowerCase(s.charAt(left)) != (Character.toLowerCase(s.charAt(right))))) {
return false;
}
left++;
right–;
}
return true;
}

解法二:栈
public boolean isPalindrome(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); ++i) {
char c = s.charAt(i);
if (c >= 48 && c <= 57 || c >= 65 && c <= 90 || c >= 97 && c <= 122) {
sb.append©;
}
}
if (sb.length() == 0) {
return true;
}
int mid = (sb.length() - 1) / 2;
Deque stack = new LinkedList<>();
for (int i = 0; i <= mid; ++i) {
stack.push(String.valueOf(sb.charAt(i)));
}
if (sb.length() % 2 == 1) {
stack.pop();
}
for (int i = mid + 1; i < sb.length(); ++i) {
if (!String.valueOf(sb.charAt(i)).equalsIgnoreCase(stack.pop())) {
return false;
}
}
return true;
}

第四题: https://leetcode-cn.com/problems/toeplitz-matrix/
解法一:暴力求解,直接找出规律即可
public boolean isToeplitzMatrix(int[][] matrix) {
int m=matrix.length,n=matrix[0].length;
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
if(matrix[i][j]!=matrix[i-1][j-1])
return false;
}
}
return true;
}
第五题:https://leetcode-cn.com/problems/find-pivot-index/
解法一:双指针暴力求解
public int pivotIndex(int[] nums) {
int left = 0;
int right = nums.length-1;
int leftSum = 0, rightSum = 0;
while(left <= right){
leftSum += nums[left];
rightSum += nums[right];
if(leftSum == rightSum){
return left+1;
}else {
left++;
right–;
}
}
return -1;
}

第六题: https://leetcode-cn.com/problems/reverse-bits/
解法一:位运算
public int reverseBits(int n) {
int rev = 0;
for (int i = 0; i < 32 && n != 0; ++i) {
rev |= (n & 1) << (31 - i);
n >>>= 1;
}
return rev;
}

第七题:https://leetcode-cn.com/problems/valid-anagram/
解法一:哈希表,key为字母,value出现次数
public boolean isAnagram(String s, String t) {
if(s.length() != t.length()){
return false;
}
HashMap<Character,Integer> map = new HashMap<>();
for(int i = 0;i < s.length();i++){
if(!map.containsKey(s.charAt(i))) {
map.put(s.charAt(i),map.getOrDefault(s.charAt(i),0)+1);
}
}
for(int j = 0;j < s.length();j++) {
if(map.containsKey(t.charAt(j))) {
if(map.get(t.charAt(j)) > 0) {
map.put(t.charAt(j),map.get(t.charAt(j))-1);
}else {
return false;
}
}
}
for(Map.Entry entry : map.entrySet()){
if(!entry.getValue().equals(0)){
return false;
}
}
return true;
}

第八题:https://leetcode-cn.com/problems/implement-queue-using-stacks/
解法一:两个栈,一个进栈,一个出栈
Deque inStack;
Deque outStack;

public MyQueue() {
inStack = new LinkedList();
outStack = new LinkedList();
}
public void push(int x) {
inStack.push(x);
}
public int pop() {
if (outStack.isEmpty()) {
in2out();
}
return outStack.pop();
}
public int peek() {
if (outStack.isEmpty()) {
in2out();
}
return outStack.peek();
}
public boolean empty() {
return inStack.isEmpty() && outStack.isEmpty();
}

private void in2out() {
while (!inStack.isEmpty()) {
outStack.push(inStack.pop());
}
}

第九题:https://leetcode-cn.com/problems/is-subsequence/
解法一:Set,将母序列放入set中,再遍历一边,看是否存在子序列
public boolean isSubsequence(String s, String t) {
HashSet set = new HashSet<>();
for(Character cur : t.toCharArray()){
set.add(cur);
}
for(Character pos : s.toCharArray()){
if(!set.contains(pos)) {
return false;
}
}
return true;
}

第十题:https://leetcode-cn.com/problems/guess-number-higher-or-lower/
解法一:二分查找
public int guessNumber(int n) {
int left = 1, right = n;
while (left < right) { // 循环直至区间左右端点相同
int mid = left + (right - left) / 2; // 防止计算时溢出
if (guess(mid) <= 0) {
right = mid; // 答案在区间 [left, mid] 中
} else {
left = mid + 1; // 答案在区间 [mid+1, right] 中
}
}
// 此时有 left == right,区间缩为一个点,即为答案
return left;
}

第十一题:https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/
解法一:动态规划
public int getMoneyAmount(int n) {
int[][] f = new int[n + 1][n + 1];
for (int i = n - 1; i >= 1; i–) {
for (int j = i + 1; j <= n; j++) {
f[i][j] = j + f[i][j - 1];
for (int k = i; k < j; k++) {
f[i][j] = Math.min(f[i][j], k + Math.max(f[i][k - 1], f[k + 1][j]));
}
}
}
return f[1][n];
}

第十二题:https://leetcode-cn.com/problems/longest-increasing-subsequence/
解法一:二分查找
public int lengthOfLIS(int[] nums) {
int len = 1, n = nums.length;
if (n == 0) {
return 0;
}
int[] d = new int[n + 1];
d[len] = nums[0];
for (int i = 1; i < n; ++i) {
if (nums[i] > d[len]) {
d[++len] = nums[i];
} else {
int l = 1, r = len, pos = 0; // 如果找不到说明所有的数都比 nums[i] 大,此时要更新 d[1],所以这里将 pos 设为 0
while (l <= r) {
int mid = (l + r) >> 1;
if (d[mid] < nums[i]) {
pos = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
d[pos + 1] = nums[i];
}
}
return len;
}
解法二:动态规划
public int lengthOfLIS(int[] nums) {
if (nums.length == 0) {
return 0;
}
int[] dp = new int[nums.length];
dp[0] = 1;
int maxans = 1;
for (int i = 1; i < nums.length; i++) {
dp[i] = 1;
for (int j = 0; j < i; j++) {
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
maxans = Math.max(maxans, dp[i]);
}
return maxans;
}

第十三题:https://leetcode-cn.com/problems/search-a-2d-matrix-ii/
解法一:二分查找
public boolean searchMatrix(int[][] matrix, int target) {
for (int[] row : matrix) {
int index = search(row, target);
if (index >= 0) {
return true;
}
}
return false;
}
public int search(int[] nums, int target) {
int low = 0, high = nums.length - 1;
while (low <= high) {
int mid = (high - low) / 2 + low;
int num = nums[mid];
if (num == target) {
return mid;
} else if (num > target) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return -1;
}
解法二:暴力查找
public boolean searchMatrix(int[][] matrix, int target) {
for (int[] row : matrix) {
for (int element : row) {
if (element == target) {
return true;
}
}
}
return false;
}

第十四题:https://blog.csdn.net/weixin_50791900/article/details/113875047
解法一:哈希表
public int findShortestSubArray(int[] nums) {
Map<Integer, int[]> map = new HashMap<Integer, int[]>();
int n = nums.length;
for (int i = 0; i < n; i++) {
if (map.containsKey(nums[i])) {
map.get(nums[i])[0]++;
map.get(nums[i])[2] = i;
} else {
map.put(nums[i], new int[]{1, i, i});
}
}
int maxNum = 0, minLen = 0;
for (Map.Entry<Integer, int[]> entry : map.entrySet()) {
int[] arr = entry.getValue();
if (maxNum < arr[0]) {
maxNum = arr[0];
minLen = arr[2] - arr[1] + 1;
} else if (maxNum == arr[0]) {
if (minLen > arr[2] - arr[1] + 1) {
minLen = arr[2] - arr[1] + 1;
}
}
}
return minLen;
}

第十五题:https://leetcode-cn.com/problems/number-of-provinces/
解法一:dfs
public int findCircleNum(int[][] isConnected) {
int provinces = isConnected.length;
boolean[] visited = new boolean[provinces];
int circles = 0;
for (int i = 0; i < provinces; i++) {
if (!visited[i]) {
dfs(isConnected, visited, provinces, i);
circles++;
}
}
return circles;
}

public void dfs(int[][] isConnected, boolean[] visited, int provinces, int i) {
for (int j = 0; j < provinces; j++) {
if (isConnected[i][j] == 1 && !visited[j]) {
visited[j] = true;
dfs(isConnected, visited, provinces, j);
}
}
}
解法二:bfs
public int findCircleNum(int[][] isConnected) {
int provinces = isConnected.length;
boolean[] visited = new boolean[provinces];
int circles = 0;
Queue queue = new LinkedList();
for (int i = 0; i < provinces; i++) {
if (!visited[i]) {
queue.offer(i);
while (!queue.isEmpty()) {
int j = queue.poll();
visited[j] = true;
for (int k = 0; k < provinces; k++) {
if (isConnected[j][k] == 1 && !visited[k]) {
queue.offer(k);
}
}
}
circles++;
}
}
return circles;
}

第十六题:https://leetcode-cn.com/problems/network-delay-time/
解法一:狄杰斯特拉算法
public int networkDelayTime(int[][] times, int n, int k) {
final int INF = Integer.MAX_VALUE / 2;
int[][] g = new int[n][n];
for (int i = 0; i < n; ++i) {
Arrays.fill(g[i], INF);
}
for (int[] t : times) {
int x = t[0] - 1, y = t[1] - 1;
g[x][y] = t[2];
}

int[] dist = new int[n];
Arrays.fill(dist, INF);
dist[k - 1] = 0;
boolean[] used = new boolean[n];
for (int i = 0; i < n; ++i) {
int x = -1;
for (int y = 0; y < n; ++y) {
if (!used[y] && (x == -1 || dist[y] < dist[x])) {
x = y;
}
}
used[x] = true;
for (int y = 0; y < n; ++y) {
dist[y] = Math.min(dist[y], dist[x] + g[x][y]);
}
}

int ans = Arrays.stream(dist).max().getAsInt();
return ans == INF ? -1 : ans;
}

第十七题:https://leetcode-cn.com/problems/sliding-window-maximum/
解法一:优先队列
public int[] maxSlidingWindow(int[] nums, int k) {
int n = nums.length;
PriorityQueue<int[]> pq = new PriorityQueue<int[]>(new Comparator<int[]>() {
public int compare(int[] pair1, int[] pair2) {
return pair1[0] != pair2[0] ? pair2[0] - pair1[0] : pair2[1] - pair1[1];
}
});
for (int i = 0; i < k; ++i) {
pq.offer(new int[]{nums[i], i});
}
int[] ans = new int[n - k + 1];
ans[0] = pq.peek()[0];
for (int i = k; i < n; ++i) {
pq.offer(new int[]{nums[i], i});
while (pq.peek()[1] <= i - k) {
pq.poll();
}
ans[i - k + 1] = pq.peek()[0];
}
return ans;
}

第十八题:https://leetcode-cn.com/problems/similar-string-groups/
解法一:并查集
int[] f;

public int numSimilarGroups(String[] strs) {
int n = strs.length;
int m = strs[0].length();
f = new int[n];
for (int i = 0; i < n; i++) {
f[i] = i;
}
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int fi = find(i), fj = find(j);
if (fi == fj) {
continue;
}
if (check(strs[i], strs[j], m)) {
f[fi] = fj;
}
}
}
int ret = 0;
for (int i = 0; i < n; i++) {
if (f[i] == i) {
ret++;
}
}
return ret;
}

public int find(int x) {
return f[x] == x ? x : (f[x] = find(f[x]));
}

public boolean check(String a, String b, int len) {
int num = 0;
for (int i = 0; i < len; i++) {
if (a.charAt(i) != b.charAt(i)) {
num++;
if (num > 2) {
return false;
}
}
}
return true;
}

第十九题:
解法:暴力求解
static int[][] arr = new int[100][100];

public static void main(String[] args) {

f();
System.out.println(arr[40][40]);

}

private static void f() {
int n = 0;
for (int i = 1; i < 100; i++) {
if (i % 2 == 1) {
for (int j = 1; j <= i; j++) {
arr[i - j + 1][j] = ++n;
}
} else {
for (int j = 1; j <= i; j++) {
arr[j][i - j + 1] = ++n;
}
}
}
}
运行结果:3121

第二十题:
解法一:
static int n = 0;

public static void main(String[] args) {
for (int i = 1; i <= 2020; i++) {
f(i);
}
System.out.println(n);
}

private static void f(int x) {
int m;
while (x != 0) {
if (x % 10 == 2) {
n++;
}
x = x / 10;
}
}
运行结果:624

第二十二题:
解法一:public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int h = sc.nextInt();
int m = sc.nextInt();
int t = sc.nextInt();
int h1=0,m1=0;
h1=t/60;
m1=t%60;
if(m1+m>=60){
m=(m1+m)%60;
h=h+1;
}
h=h+1;
System.out.println(h);
System.out.println(m);
}
运行结果:23 59 14 25 23

第二十三题:
解法一:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
char[] a = s.toCharArray();
int count = 0;
for(int i = 0;i < a.length-1;i++){
for(int j = a.length-1;j >i ;j–){
count = count + Math.abs(a[i]-a[j]);
}
}
System.out.println(count);
}
运行结果:1132

第二十四题:
解法一:public static void main(String[] args) {

int[][] step = new int[39][2];// 第一维是39层阶梯,第二维是左右脚

// 对于第一级阶梯,左脚有1种方法到达,右脚0种(因为题目要求先迈左脚)
step[0][0] = 1;
step[0][1] = 0;

// 对于第二级阶梯,左脚有1种方法到达,因为每一步只能迈上1或2 个台阶,右脚有1种
step[1][0] = 1;
step[1][1] = 1;

for (int i = 2; i < 39; i++) {
    step[i][1] = step[i - 2][0] + step[i - 1][0];
    step[i][0] = step[i - 2][1] + step[i - 1][1];
}

System.out.println(step[38][1]);

}
运行结果:51167078

标签:return,nums,int,length,初赛,++,算法,public,解答
来源: https://blog.csdn.net/weixin_45784732/article/details/121490735